我可以使用:
if A:
而不是
if A is not None:
后者似乎太啰嗦了。有区别吗?
我可以使用:
if A:
而不是
if A is not None:
后者似乎太啰嗦了。有区别吗?
当前回答
前者更Pythonic(更好的理想代码),但如果A为False(不是None),则不会执行块。
其他回答
他们做的事情非常不同。
下面检查A除了False、[]、None和0之外是否有其他值。它检查A的值。
if A:
下面检查A是否与None是不同的对象。它检查并比较A和None的引用(内存地址)。
if A is not None:
更新:进一步解释
很多时候,这两者似乎做同样的事情,所以很多人互换使用它们。两者给出相同结果的原因是由于解释器/编译器的优化,如实习或其他原因,很多时候纯属巧合。
考虑到这些优化,相同值的整数和字符串最终将使用相同的内存空间。这可能解释了为什么两个独立的弦表现得好像是一样的。
> a = 'test'
> b = 'test'
> a is b
True
> a == b
True
其他的事情就不一样了。
> a = []
> b = []
> a is b
False
> a == b
True
这两个列表显然有自己的记忆。令人惊讶的是,元组的行为与字符串相似。
> a = ()
> b = ()
> a is b
True
> a == b
True
这可能是因为元组被保证不会改变,因此重用相同的内存是有意义的。
这表明您应该对所使用的比较运算符格外警惕。根据您真正想检查的内容使用is和==。这些东西很难调试,因为它读起来就像散文,我们经常只是粗略地浏览它。
if A:如果A为0,false,空字符串,空列表或None,将证明为假,这可能导致不希望的结果。
我创建了一个名为test.py的文件,并在解释器上运行它。您可以更改您想要更改的内容,以确定事情在幕后是如何进行的。
import dis
def func1():
matchesIterator = None
if matchesIterator:
print( "On if." );
def func2():
matchesIterator = None
if matchesIterator is not None:
print( "On if." );
print( "\nFunction 1" );
dis.dis(func1)
print( "\nFunction 2" );
dis.dis(func2)
这是汇编程序的区别:
来源:
>>> import importlib
>>> reload( test )
Function 1
6 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
8 6 LOAD_FAST 0 (matchesIterator)
9 POP_JUMP_IF_FALSE 20
10 12 LOAD_CONST 1 ('On if.')
15 PRINT_ITEM
16 PRINT_NEWLINE
17 JUMP_FORWARD 0 (to 20)
>> 20 LOAD_CONST 0 (None)
23 RETURN_VALUE
Function 2
14 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
16 6 LOAD_FAST 0 (matchesIterator)
9 LOAD_CONST 0 (None)
12 COMPARE_OP 9 (is not)
15 POP_JUMP_IF_FALSE 26
18 18 LOAD_CONST 1 ('On if.')
21 PRINT_ITEM
22 PRINT_NEWLINE
23 JUMP_FORWARD 0 (to 26)
>> 26 LOAD_CONST 0 (None)
29 RETURN_VALUE
<module 'test' from 'test.py'>
如PEP8所写:
应该始终对像None这样的单例对象进行比较 'is'或'is not',绝不是相等运算符。 另外,当你真正想要表达的是“如果x不是None”时,注意不要写成“if x” ——例如,当测试一个变量或参数是否默认为 None被设置为其他值。另一个值可能有类型 (例如容器)在布尔上下文中可能是假的!
前者更Pythonic(更好的理想代码),但如果A为False(不是None),则不会执行块。