猿问
下载APP

为什么“if not someobj:”比Python中的“if someobj == None:”

我见过几个像这样的代码示例:


if not someobj:

    #do something

但我想知道为什么不这样做:


if someobj == None:

    #do something

有什么区别吗?一个人比另一个人有优势吗?


德玛西亚99
浏览 63回答 3
3回答

千万里不及你

在第一个测试中,Python尝试将对象转换为bool值,如果它不是一个值。粗略地说,我们问的对象是:你有意义吗?这是使用以下算法完成的:如果对象有一个__nonzero__特殊的方法(如做数字内置插件,int和float),它会调用这个方法。它必须返回一个bool直接使用的int值,或者False如果等于零则返回一个值。否则,如果对象有一个__len__特殊的方法(如做容器内置插件,list,dict,set,tuple,...),它会调用这个方法,考虑一个容器False,如果它是空的(长度为零)。否则,True除非None在这种情况下考虑对象,否则考虑该对象False。在第二个测试中,比较对象的相等性None。在这里,我们问对象,“你是否等于这个其他价值?” 这是使用以下算法完成的:如果对象有一个__eq__方法,则调用它,然后将返回值转换为一个bool值并用于确定结果if。否则,如果对象有__cmp__方法,则调用它。此函数必须返回int指示两个对象的顺序(-1if self < other,0if self == other,+1if self > other)。否则,比较对象的标识(即,它们是对同一对象的引用,可以由is运营商测试)。使用is操作员可以进行另一项测试。我们会问对象,“你是这个特殊的对象吗?”一般来说,我建议使用非数值的第一个测试,当你想要比较相同性质的对象(两个字符串,两个数字......)并且仅在检查身份时才使用测试进行相等使用sentinel值(None意味着没有为成员字段初始化为例,或者使用getattr或者使用__getitem__方法)。总而言之,我们有:>>> class A(object):...&nbsp; &nbsp; def __repr__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return 'A()'...&nbsp; &nbsp; def __nonzero__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return False>>> class B(object):...&nbsp; &nbsp; def __repr__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return 'B()'...&nbsp; &nbsp; def __len__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return 0>>> class C(object):...&nbsp; &nbsp; def __repr__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return 'C()'...&nbsp; &nbsp; def __cmp__(self, other):...&nbsp; &nbsp; &nbsp; &nbsp; return 0>>> class D(object):...&nbsp; &nbsp; def __repr__(self):...&nbsp; &nbsp; &nbsp; &nbsp; return 'D()'...&nbsp; &nbsp; def __eq__(self, other):...&nbsp; &nbsp; &nbsp; &nbsp; return True>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:...&nbsp; &nbsp; &nbsp;print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(repr(obj), bool(obj), obj == None, obj is None)&nbsp; '': bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp; (): bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp; []: bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp; {}: bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp; &nbsp;0: bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp;0.0: bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp;A(): bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp;B(): bool(obj) -> False, obj == None -> False, obj is None -> False&nbsp;C(): bool(obj) ->&nbsp; True, obj == None ->&nbsp; True, obj is None -> False&nbsp;D(): bool(obj) ->&nbsp; True, obj == None ->&nbsp; True, obj is None -> FalseNone: bool(obj) -> False, obj == None ->&nbsp; True, obj is None ->&nbsp; True

若吾皇

这些实际上都是不良做法。曾几何时,认为随意对待None和False是相似的。但是,从Python 2.2开始,这不是最好的策略。首先,当你进行一种if x或if not x那种测试时,Python必须隐式转换x为boolean。bool函数的规则描述了一大堆错误的东西; 其他一切都是真的。如果x的值在开始时没有正确的布尔值,那么这种隐式转换实际上并不是最清楚的说法。在Python 2.2之前,没有bool函数,所以它更不清楚。其次,你不应该真的测试== None。你应该使用is None和is not None。请参阅PEP 8,Python代码样式指南。- Comparisons to singletons like None should always be done with&nbsp; 'is' or 'is not', never the equality operators.&nbsp; Also, beware of writing "if x" when you really mean "if x is not None"&nbsp; -- e.g. when testing whether a variable or argument that defaults to&nbsp; None was set to some other value.&nbsp; The other value might have a type&nbsp; (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。

慕容森

因为None并不是唯一被认为是错误的东西。if not False:&nbsp; &nbsp; print "False is false."if not 0:&nbsp; &nbsp; print "0 is false."if not []:&nbsp; &nbsp; print "An empty list is false."if not ():&nbsp; &nbsp; print "An empty tuple is false."if not {}:&nbsp; &nbsp; print "An empty dict is false."if not "":&nbsp; &nbsp; print "An empty string is false."False,0,(),[],{}和""是从各个不同的None,所以你的两段代码是不等价的。此外,请考虑以下事项:>>> False == 0True>>> False == ()Falseif object:是不是相等性检查。0,(),[],None,{},等是所有彼此不同,但他们都评价为False。这是短路表达背后的“魔力”,如:foo = bar and spam or eggs这是简写:if bar:&nbsp; &nbsp; foo = spamelse:&nbsp; &nbsp; foo = eggs虽然你真的应该写:foo = spam if bar else egg
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答