我可以使用:
if A:
而不是
if A is not None:
后者似乎太啰嗦了。有区别吗?
我可以使用:
if A:
而不是
if A is not None:
后者似乎太啰嗦了。有区别吗?
当前回答
这取决于上下文。
我使用if A:当我期望A是某种类型的集合时,我只想在集合不为空的情况下执行块。这允许调用者传递任何行为良好的集合,无论是否为空,并让它执行我所期望的操作。它还允许None和False抑制块的执行,这偶尔对调用代码很方便。
OTOH,如果我期望A是一些完全任意的对象,但它可以默认为None,那么我总是使用if A不是None,因为调用代码可以故意传递一个引用到一个空集合,空字符串,或一个0值的数字类型,或布尔False,或一些类实例,在布尔上下文中恰好为假。
另一方面,如果我期望A是一些更具体的东西(例如,我要调用方法的一个类的实例),但它可以默认为None,并且我认为默认布尔转换是类的属性,我不介意对所有子类强制执行,那么我只使用if A:来节省我的手指输入额外12个字符的可怕负担。
其他回答
我创建了一个名为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'>
None是Python中的一个特殊值,通常指定一个未初始化的变量。要测试A是否没有这个特定的值,可以使用:
if A is not None
Falsey值是Python中一类特殊的对象(例如false,[])。要测试A是否是假的,请使用:
if not A
因此,这两种表达方式是不一样的,你最好不要把它们当作同义词。
附注:None也是假的,所以第一个表达暗示了第二个表达。但是第二个包含了除了None之外的其他错误值。现在…如果你能确定在A中除了None之外没有其他假值,那么你可以用第二个表达式替换第一个表达式。
如PEP8所写:
应该始终对像None这样的单例对象进行比较 'is'或'is not',绝不是相等运算符。 另外,当你真正想要表达的是“如果x不是None”时,注意不要写成“if x” ——例如,当测试一个变量或参数是否默认为 None被设置为其他值。另一个值可能有类型 (例如容器)在布尔上下文中可能是假的!
这取决于上下文。
我使用if A:当我期望A是某种类型的集合时,我只想在集合不为空的情况下执行块。这允许调用者传递任何行为良好的集合,无论是否为空,并让它执行我所期望的操作。它还允许None和False抑制块的执行,这偶尔对调用代码很方便。
OTOH,如果我期望A是一些完全任意的对象,但它可以默认为None,那么我总是使用if A不是None,因为调用代码可以故意传递一个引用到一个空集合,空字符串,或一个0值的数字类型,或布尔False,或一些类实例,在布尔上下文中恰好为假。
另一方面,如果我期望A是一些更具体的东西(例如,我要调用方法的一个类的实例),但它可以默认为None,并且我认为默认布尔转换是类的属性,我不介意对所有子类强制执行,那么我只使用if A:来节省我的手指输入额外12个字符的可怕负担。
如果没有合适的结果,许多函数将返回None。例如,如果结果中没有行,SQLAlchemy查询的.first()方法将返回None。假设您正在选择一个可能返回0的值,并且需要知道它实际上是0还是查询根本没有结果。
一个常见的习惯是给函数或方法的可选参数设置默认值None,然后测试该值是否为None,以确定是否指定了该值。例如:
def spam(eggs=None):
if eggs is None:
eggs = retrievefromconfigfile()
将其与:
def spam(eggs=None):
if not eggs:
eggs = retrievefromconfigfile()
在后者中,如果调用spam(0)或spam([])会发生什么?该函数将(错误地)检测到您没有为eggs传递一个值,并为您计算一个默认值。这可能不是你想要的。
或者想象一个类似于“返回给定帐户的交易列表”的方法。如果该帐户不存在,则可能返回None。这与返回空列表(空列表意味着“此帐户存在,但没有记录交易)不同。
最后,回到数据库。NULL和空字符串之间有很大的区别。空字符串通常表示“这里有一个值,这个值什么都不是”。NULL表示“该值未被输入”。
在每一种情况下,你都想使用if A = None。您正在检查一个特定的值—None—而不仅仅是“恰好转换为False的任何值”。