我见过几个这样的代码示例:
if not someobj:
#do something
但我想知道为什么不这样做:
if someobj == None:
#do something
有什么区别吗?一个人比另一个人有优势吗?
答案 0 :(得分:172)
在第一个测试中,Python尝试将对象转换为bool
值,如果它不是一个值。粗略地,我们问对象:你有意义吗?这是使用以下算法完成的:
如果对象具有__nonzero__
特殊方法(与数字内置函数int
和float
一样),则会调用此方法。它必须返回直接使用的bool
值,或者如果等于零则返回int
False
值。
否则,如果对象具有__len__
特殊方法(容器内置插件,list
,dict
,set
,{{1} },...),如果容器tuple
为空(长度为零),则调用此方法。
否则,该对象将被视为False
,除非它是True
,在这种情况下,它被视为None
。
在第二个测试中,将对象与False
进行相等性比较。在这里,我们问对象,“你是否等于这个其他值?”这是使用以下算法完成的:
如果对象具有None
方法,则会调用该方法,然后将返回值转换为__eq__
值并用于确定bool
的结果
否则,如果对象具有if
方法,则调用它。此函数必须返回__cmp__
,指示两个对象的顺序(int
如果-1
,self < other
如果0
,self == other
if {{ 1}})。
否则,对象的身份进行比较(即,他们引用同一个对象,可以由+1
运算符进行测试)。
使用self > other
运算符可以进行另一项测试。 我们会问对象,“你是这个特殊的对象吗?”
一般情况下,我建议使用非数值的第一个测试,当你想要比较相同性质的对象(两个字符串,两个数字......)并检查时,使用测试进行相等仅在使用标记值时才标识(is
表示未针对例如成员字段初始化,或者使用is
或None
方法时)。
总结一下,我们有:
getattr
答案 1 :(得分:45)
这些实际上都是不良做法。曾几何时,认为随意对待None和False是相似的。但是,从Python 2.2开始,这不是最好的策略。
首先,当你进行if x
或if not x
类测试时,Python必须隐式地将x
转换为布尔值。 bool
函数的规则描述了一大堆错误的东西;其他一切都是真的。如果x的值在开始时没有正确的布尔值,那么这种隐式转换实际上并不是最清楚的说法。
在Python 2.2之前,没有bool函数,因此它更不清楚。
其次,你不应该用== None
进行真正的测试。您应该使用is None
和is not None
。
参见PEP 8,Style Guide for Python Code。
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators. Also, beware of writing "if x" when you really mean "if x is not None" -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
有多少单身人士?五:None
,True
,False
,NotImplemented
和Ellipsis
。由于您真的不太可能使用NotImplemented
或Ellipsis
,并且您永远不会说if x is True
(因为简单地if x
更加清晰),您只会测试None
。
答案 2 :(得分:32)
因为None
不是唯一被认为是假的东西。
if not False:
print "False is false."
if not 0:
print "0 is false."
if not []:
print "An empty list is false."
if not ():
print "An empty tuple is false."
if not {}:
print "An empty dict is false."
if not "":
print "An empty string is false."
False
,0
,()
,[]
,{}
和""
都与None
不同,所以两个代码段不等于。
此外,请考虑以下事项:
>>> False == 0
True
>>> False == ()
False
if object:
不是一个等式检查。 0
,()
,[]
,None
,{}
等 彼此不同,但它们全部< em>评估为False。
这是短路表达式背后的“魔力”,如:
foo = bar and spam or eggs
这是:
的简写if bar:
foo = spam
else:
foo = eggs
虽然你真的应该写:
foo = spam if bar else egg
答案 3 :(得分:3)
PEP 8 -- Style Guide for Python Code建议您使用 或 不 ,如果您要测试的是岬
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators.
另一方面,如果你测试的不是None-ness,你应该使用布尔运算符。
答案 4 :(得分:3)
如果你问
if not spam:
print "Sorry. No SPAM."
垃圾邮件的 __非零__ 方法被调用。从Python手册:
<强> __非零__ 强>(自) 被称为实施真值测试,内置操作bool();应该返回False或True,或者它们的整数等价于0或1.如果未定义此方法,则调用__len __()(如果已定义)(见下文)。如果一个类既没有定义__len __()也没有定义__nonzero __(),那么它的所有实例都被认为是真的。
如果你问
if spam == None:
print "Sorry. No SPAM here either."
使用参数无调用垃圾邮件的 __ eq __ 方法。
有关自定义可能性的更多信息,请查看https://docs.python.org/reference/datamodel.html#basic-customization
上的Python文档。答案 5 :(得分:2)
这两个比较用于不同的目的。前者检查某物的布尔值,第二种检查具有无值的身份。
答案 6 :(得分:0)
首先,第一个例子更短,看起来更好。根据其他帖子,你选择的还取决于你真正想要做的比较。
答案 7 :(得分:0)
答案是“它取决于”。
如果我将0,“”,[]和False(列表并非详尽无遗)视为在此上下文中等于None,我会使用第一个示例。
答案 8 :(得分:0)
就个人而言,我选择了跨语言的一致方法:只有当var声明为boolean(或者在C中定义,我们没有特定类型)时,我才会if (var)
(或等效)。我甚至用b
(这实际上是bVar
)为这些变量添加前缀,以确保我不会在这里意外使用其他类型。
我真的不喜欢隐式转换为布尔值,更不用说有很多复杂的规则了。
当然,人们会不同意。有些走得更远,我在工作中的Java代码中看到if (bVar == true)
(对我来说太多了!),其他人喜欢太紧凑的语法,转向while (line = getNextLine())
(对我来说太模糊了)。