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

时间:2011-06-23 19:21:27

标签: python idioms

Python的Zen说明确比隐含更好。

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

if not c:
    # ...

并检查集合是否为空,如下所示:

if c:
    # ...

同样可以有“zeroness”或“空虚”(元组,整数,字符串,无等)的任何内容

这是为了什么目的?如果我不这样做,我的代码会变得更加困难吗?或者它是否会启用更多用例(即:某种多态),因为人们可以覆盖这些布尔强制?

8 个答案:

答案 0 :(得分:18)

这种最佳做法并非没有道理。

在测试if object:时,您基本上调用了对象__nonzero__方法,该方法可以根据对象行为进行覆盖和实现。

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

(参考:http://docs.python.org/reference/datamodel.html

答案 1 :(得分:8)

“简单比复杂更好。”

“可读性很重要。”

if users为例 - if len(users) == 0

更具可读性

答案 2 :(得分:7)

可能被第一和第三项胜过:

  • 美丽胜过丑陋。
  • 简单比复杂更好。

答案 3 :(得分:5)

if c:
    # ...

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

认为

是公平的
if c == 0:
    # ...

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

但对于经验丰富的程序员(至少这一个),后者并不清楚,这是多余的。我已经知道c会因为“if”而与0进行比较;我不需要被告知两次。

答案 4 :(得分:4)

如果您愿意,可以输入if len(lst) > 0,但重点是什么? Python确实使用了一些约定,其中一个是空容器被认为是假的。

您可以使用object.__nonzero__(self)自定义此内容:

  

被要求实施真理价值   测试和内置操作   布尔();应该返回False或True,   或等于0或1的整数。   如果未定义此方法,   如果是,则调用__len__()   定义,并考虑对象   如果结果非零,则返回true。如果一个   class既不定义__len__()也不定义   __nonzero__(),其所有实例都是   被认为是真的。

答案 5 :(得分:4)

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

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__定义的布尔转换。

答案 6 :(得分:2)

其他人已经注意到这是传统的逻辑延伸(至少早在C,也许更早),在布尔上下文中零是错误的,非零是真的。其他人也已经注意到在Python中你可以使用自定义魔术方法等来实现一些特殊效果。 (这确实直接回答了你的问题“它是否能够实现更多用例?”)其他人已经注意到,有经验的Python程序员将学会这种约定并习惯于约定,因此对他们来说非常明显和明确。

但老实说,如果你不喜欢这种惯例,而你只是为了自己的享受和受益而编程,只需不要遵循它。显而易见,清晰,和冗余比使用模糊处理更好,更多,并且在冗余方面比混淆更容易犯错误。

也就是说,当它归结为它时,它并不是一个难以学习的习惯,如果你作为小组项目的一部分进行编码,最好坚持项目的惯例,即使你不同意它们。

答案 7 :(得分:1)

评估为 False 的空列表和评估为 True 的非空列表是一个非常明确的中心Python约定。如果if语句的上下文甚至传达了c是列表的事实,那么len(c) == 0就不会更明确。

我认为len(c) == 0只是更明确,如果你真的想检查长度而不是魔法 zeroness 空虚,因为他们的评价可能与长度检查。