为什么在 Python 中隐式检查是否为空?

发布于 2024-11-16 16:03:27 字数 295 浏览 3 评论 0原文

Python 的禅宗说显式优于隐式。

然而,检查集合 c 是否为空的 Pythonic 方法是:

if not c:
    # ...

检查集合是否不为空的方法如下:

if c:
    # ...

对于任何可能具有“零”或“空”的内容(元组、整数、字符串、无等),

同上这样做的目的是什么?如果我不这样做,我的代码会出现更多错误吗?或者它是否支持更多用例(即:某种多态性),因为人们可以覆盖这些布尔强制?

The Zen of Python says that explicit is better than implicit.

Yet the Pythonic way of checking a collection c for emptiness is:

if not c:
    # ...

and checking if a collection is not empty is done like:

if c:
    # ...

ditto for anything that can have "zeroness" or "emptiness" (tuples, integers, strings, None, etc)

What is the purpose of this? Will my code be buggier if I don't do this? Or does it enable more use cases (i.e: some kind of polymorphism) since people can override these boolean coercions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

何处潇湘 2024-11-23 16:03:27

这种最佳实践并非没有道理。

在测试 if object: 时,您基本上是在调用对象的 __bool__ 方法,该方法可以根据对象行为进行重写和实现。

例如,集合上的 __bool__ 方法(Python 2 中的 __nonzero__)将根据集合是否为空返回一个布尔值。

(参考:http://docs.python.org/reference/datamodel.html< /a>)

This best practice is not without reason.

When testing if object: you are basically calling the objects __bool__ method, which can be overridden and implemented according to object behavior.

For example, the __bool__ method on collections (__nonzero__ in Python 2) will return a boolean value based on whether the collection is empty or not.

(Reference: http://docs.python.org/reference/datamodel.html)

晨曦慕雪 2024-11-23 16:03:27

可能被第一条和第三条打败:

  • 美丽比丑陋好。
  • 简单总比复杂好。

Possibly trumped by the first and third items:

  • Beautiful is better than ugly.
  • Simple is better than complex.
暖风昔人 2024-11-23 16:03:27

“简单总比复杂好。”

“可读性很重要。”

if users 为例 - 它比 if len(users) == 0 更具可读性

"Simple is better than complex."

"Readability counts."

Take for example if users -- it is more readable that if len(users) == 0

海未深 2024-11-23 16:03:27
if c:
    # ...

是明确的。 “if”明确指出后面的表达式将在布尔上下文中计算。

公平地说,这样

if c == 0:
    # ...

更清晰,编程新手可能会同意。

但对于一个有经验的程序员(至少是这个)来说,后者并不清晰,它是多余的。由于“if”,我已经知道 c 将与 0 进行比较;我不需要被告知两次。

if c:
    # ...

is explicit. The "if" explicitly states that the expression following will be evaluated in boolean context.

It is fair to argue that

if c == 0:
    # ...

is clearer, and a programming novice might agree.

But to an experienced programmer (this one at least) the latter is not clearer, it is redundant. I already know c will be compared with 0 because of the "if"; I don't need to be told twice.

谁许谁一生繁华 2024-11-23 16:03:27

隐式布尔多态性是许多语言的一部分。事实上,这个习语

if msg:
    print str(len(msg)) + ' char message: ' + msg

可以说来自 c!

void print_msg(char * msg) {
    if (msg) {
        printf("%d char message: %s", (int) strlen(msg), msg);
    }
}

未分配的指针应包含 NULL,它可以方便地计算为 false,从而使我们能够避免分段错误。

这是一个非常基本的概念,以至于Python很难拒绝它。事实上,考虑到 c 中可用的布尔多态性相当笨拙的版本,很明显(至少对我来说)Python 通过允许任何类型具有可定制的,使得这种行为更加明确。 - 通过 __nonzero__ 定义布尔转换。

Implicit boolean polymorphism is a part of many languages. In fact, the idiom

if msg:
    print str(len(msg)) + ' char message: ' + msg

arguably comes from c!

void print_msg(char * msg) {
    if (msg) {
        printf("%d char message: %s", (int) strlen(msg), msg);
    }
}

An unallocated pointer should contain NULL, which conveniently evaluates to false, allowing us to avoid a segmentation fault.

This is such a fundamental concept that it would hamper python to reject it. In fact, given the fairly clumsy version of boolean polymorphism available in c, it's immediately clear (to me at least) that python has made this behavior much more explicit by allowing any type to have a customizable, well-defined boolean conversion via __nonzero__.

执手闯天涯 2024-11-23 16:03:27

如果您愿意,可以输入 if len(lst) > 0,但这有什么意义呢? Python 确实使用一些约定,其中之一是空容器被认为是错误的。

您可以使用 object.__nonzero__(self)

调用以实现真值
测试和内置操作
bool();应返回 FalseTrue
或其整数等值 01
当这个方法没有定义时,
如果是,则调用 __len__()
定义,并且该对象被认为
如果其结果非零,则为 true。如果一个
类既不定义 __len__() 也不定义
__nonzero__(),它的所有实例都是
被认为是正确的。

If you prefer you can type if len(lst) > 0, but what would be the point? Python does use some conventions, one of which is that empty containers are considered falseish.

You can customize this with object.__nonzero__(self):

Called to implement truth value
testing and the built-in operation
bool(); should return False or True,
or their integer equivalents 0 or 1.
When this method is not defined,
__len__() is called, if it is
defined, and the object is considered
true if its result is nonzero. If a
class defines neither __len__() nor
__nonzero__(), all its instances are
considered true.

淡紫姑娘! 2024-11-23 16:03:27

其他人已经指出,这是传统的逻辑延伸(至少早在 C 语言中,也许更早),即布尔上下文中零为假,非零为真。其他人也已经注意到,在 Python 中,您可以通过自定义魔术方法等实现一些特殊效果。 (这确实直接回答了您的问题“它是否支持更多用例?”)其他人已经注意到,经验丰富的 Python 程序员将学习此约定并习惯该约定,因此这对他们来说是非常明显和明确的。

但老实说,如果您不喜欢这个惯例,并且您只是为了自己的乐趣和利益而编程,那么不要遵循它。明确、清晰、冗余比混淆要好得多,而且事实上,犯冗余总是比混淆要好。

也就是说,归根结底,这并不是一个很难学习的约定,如果您作为小组项目的一部分进行编码,那么最好遵守项目的约定,即使您不同意它们。

Others have already noted that this is a logical extension of the tradition (at least as early as C, perhaps earlier) that zero is false in a Boolean context, and nonzero is true. Others have also already noted that in Python you can achieve some special effects with customized magic methods and such. (And this does directly answer your question "does it enable more use cases?") Others have already noted that experienced Python programmers will have learned this convention and be used to the convention, so it is perfectly obvious and explicit to them.

But honestly, if you don't like that convention, and you are just programming for your own enjoyment and benefit, simply don't follow it. It is much, much better to be explicit, clear, and redundant than it is to be obfuscated, and it's virtually always better to err on the side of redundancy than obfuscation.

That said, when it comes down to it, it's not a difficult convention to learn, and if you are coding as part of a group project, it is best to stick with the project's conventions, even if you disagree with them.

埖埖迣鎅 2024-11-23 16:03:27

空列表的计算结果为 False 和非空列表的计算结果为 True 是 Python 的核心约定,它足够明确。如果 if 语句的上下文甚至传达了 c 是一个列表的事实,那么 len(c) == 0 也不会更明确。

我认为len(c) == 0只有当你真的想检查长度而不是魔术时才更明确,因为他们的评估可能与长度检查不同。

Empty lists evaluating to False and non-empty lists evaluating to True is such a central Python convention that it is explicit enough. If the context of the if-statement even communicates the fact that c is a list, len(c) == 0 wouldn't be much more explicit.

I think len(c) == 0 only is more explicit if you really want to check the length and not for magic zeroness or emptiness because their evaluation may differ from the length check.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文