熊猫应该灭绝
Pandas Should Go Extinct

原始链接: https://eddie.codes/posts/pandas-should-go-extinct/

有效的代码注释应传达意图,而非重述显而易见的事实。为保持文档整洁、有用,请遵循以下启发式原则: * **永远不要解释“是什么”:** 避免解释基础语法或不言自明的代码。过度注释会制造噪音,并暗示代码本身缺乏清晰度。 * **有时说明“为什么”:** 对偏离标准实践或“最小惊奇原则”的决策进行解释。这为非传统方案提供了背景信息,让未来的开发者能够理解并最终清理技术债。 * **始终说明“为什么不”:** 如果你刻意避开了显而易见或更好的解决方案,请记录你的理由。这可以主动回答审阅者的问题,并解释为何选择当前的“权宜之计”而非永久修复。 最后,避免使用注释与大语言模型交流或记录临时的调试思路。这些笔记没有任何长期价值,很快就会过时,且会扰乱代码库。归根结底,你的注释应通过解释选择背后的“逻辑”,而非代码本身的运行机制,来服务于未来的读者。

Hacker News 的讨论围绕着一篇名为《Pandas 应该灭绝》的文章展开。该文章认为,与 Polars 和 DuckDB 等现代替代方案相比,Python 的 `pandas` 库已经过时。 **辩论要点:** * **性能与 API:** 支持转向的一方强调,Polars 和 DuckDB 提供了显著更优的性能、更低的内存占用以及更直观的声明式 API。许多用户认为 `pandas` 的语法(特别是在分组和转换操作方面)非常繁琐,且容易出现“自陷阱”问题。 * **Pandas 的立足点:** 支持者认为,`pandas` 依然是业界的中流砥柱,这得益于其庞大的生态系统、与机器学习库(如 Scikit-Learn)的无缝集成,以及丰富的教学资源。对许多人来说,其普及性使其成为处理中小型数据集时最实用的选择。 * **语境细微差别:** 评论者指出,“大数据”工具往往被过度使用;许多使用 `pandas` 的项目实际上并未遇到内存或速度瓶颈。不过,大家的共识是,对于“新”项目,转向现代化的专业工具是明智之举。 * **元评论:** 该讨论串还针对其“标题党”风格进行了一些调侃,一些读者最初被误导,以为是在讨论生物学上的大熊猫。
相关文章

原文

Comments in your code are the simplest and often most useful means of documenting your decisions and communicating intent for those that need to understand it in the future.

However, one must be careful to ensure that the comments one leaves behind are not noisy or misleading. My general philosophy when it comes to comments is as follows:

Never tell me what, sometimes tell me why, always tell me why not.

As with all things in software, this principle is not hard and fast, but a general heuristic.

The easiest way to explain this is by example. Imagine we are writing a small helper function for filtering inactive users out of a list of users we are pulling from our database.

Never tell me what

Do not explain concepts or approaches that a seasoned programmer looking at the code can plainly understand. This is something I often see novice programmers do - they project their lack of comprehension of the basics onto the reader in the form of over-documented code.

const getActiveUsers = (users: User[]) => {
    // Iterate through each of the users and check whether their `isActive` property is true.
    return users.filter(({ isActive }) => !!isActive)
}

This comment is useless for anyone with a moderate understanding of Typescript syntax and idioms. It is the bread and butter of the language.

Sometimes tell me why

Usually, when you are doing something that violates the Principle of Least Surprise, you should consider explaining to me why you’ve made that decision.

const getActiveUsers = (users: User[]) => {
    // We need to filter out inactive users here because we don't have a DB index on the `isActive` field. Filtering here keeps latency down at the expense of less full, or potentially empty pages
    return users.filter(({ isActive }) => !!isActive)
}

This is significantly better. As a reviewer, I understand why we’re doing something nasty that should really be handled by the database.

If I come back to this in 6 months and the index has been provisioned, I now understand why we needed this and why it’s no longer necessary. I am empowered to remove this nasty code because I understand why it existed in the first place.

Always tell me why not

If there is an obvious solution to a problem which you have deliberately avoided, you should definitely tell me why you’ve done that. Most of the time, when I’m reviewing code with “tell me why” comments, my immediate next question is going to be “why not X?”, if X is an obvious solution to the problem.

By adding it to your comment, you’re helping me as a reviewer, and the next person who has to read this understand why you avoided the obvious fix.

const getActiveUsers = (users: User[]) => {
    // We need to filter out inactive users here because we don't have a DB index on the `isActive` field. Filtering here keeps latency down at the expense of less full, or potentially empty pages
    // Ideally we'd just provision the index and remove the need for this. We're adding this as a stop-gap measure as a backend deploy is quicker than a migration to add an index. Adding the index is tracked in XXX-123
    return users.filter(({ isActive }) => !!isActive)
}

This is extremely useful as I now understand why you’ve avoided the obvious fix. If I come across this in the future I can track whether the obvious fix was ever actioned, and if not, potentially action it myself.

I have expressed the sentiments in this post a few times throughout my career, and pretty much always in the terms described above. This section is a new entry to the philosophy owing to a particular conceit of LLMs: using comments as a way of communicating with their handler.

These are probably the worst comments possible as they offer no signal beyond the session in which they were created, are stale by the time the code in question is reviewed, and are putrid by the time another reader comes across them. They look like this:

const getActiveUsers = (users: User[]) => {
    // FIX: The database layer returned inactive users, filtering them here stops inactive users appearing on the admin dashboard.
    return users.filter(({ isActive }) => !!isActive)
}

This gives me a big dose of what, a small side serving of why, and absolutely no “why not”.

联系我们 contact @ memedata.com