问题:如果A vs如果A不为None:
我可以用吗:
if A:
代替
if A is not None:
后者似乎太冗长。有区别吗?
回答 0
该声明
if A:
将调用A.__nonzero__()
(请参阅特殊方法名称文档)并使用该函数的返回值。总结如下:
object.__nonzero__(self)
调用实现真值测试和内置操作
bool()
;应该返回False
或True
,或者它们的整数等效值0
或1
。如果未定义此方法,__len__()
则调用该方法(如果已定义),并且如果其结果为非零,则认为该对象为true。如果一个类既未定义,也__len__()
未定义__nonzero__()
,则其所有实例均被视为true。
另一方面,
if A is not None:
仅将参考A
与进行比较None
以查看其是否相同。
回答 1
如PEP8所述:
与单例(如None)的 比较应始终使用“ is”或“ is not”进行,永远不要使用相等运算符进行。
另外,要当心您的意思是“如果x不是None”时要写“ if x” -例如,在测试是否将默认为None的变量或参数设置为其他值时。另一个值可能具有在布尔上下文中可能为false的类型(例如容器)!
回答 2
if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None
所以不一样
if x is not None # which works only on None
回答 3
如果没有适当的结果,很多函数将返回None。例如,.first()
如果结果中没有行,则SQLAlchemy查询的方法将返回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
并会为您计算默认值。那可能不是您想要的。
或设想一种诸如“返回给定帐户的交易列表”之类的方法。如果该帐户不存在,则可能返回无。这不同于返回一个空列表(这意味着“此帐户存在,但尚未记录交易”)。
最后,回到数据库。NULL和空字符串之间有很大的区别。一个空字符串通常会说“这里有一个值,而这个值根本没有任何东西”。NULL表示“尚未输入此值”。
在每种情况下,您都想使用if A is None
。您正在检查一个特定的值-无-不只是“碰巧转换为False的任何值”。
回答 4
他们做的事情截然不同。
下面的检查是否有不同的价值观什么False
,[]
,None
,''
和0
。它检查A 的值。
if A:
下面检查A是否是不同于None的对象。它检查并比较A和None 的引用(内存地址)。
if A is not None:
更新:进一步的说明
两者似乎经常做同样的事情,所以很多人可以互换使用它们-这是一个非常糟糕的主意。由于解释器/编译器的优化(例如interning或其他方法)的优化,纯属巧合,因此两者给出相同结果的原因很多次。
考虑到这些优化,相同值的整数和字符串最终将使用相同的内存空间。这可能可以解释为什么两个单独的字符串看起来像是一样的。
> 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
和==
依赖于你真正想要检查。这些内容可能很难调试,因为is
我们常常只是略读散文,就像散文一样。
回答 5
if A:
如果A为0,False,空字符串,空列表或None,则将证明为false,这可能导致不良结果。
回答 6
我见过的大多数指南都建议您使用
如果一个:
除非您有理由更具体。
有一些细微的差异。除了None以外,还有其他值返回False,例如空列表或0,因此请考虑一下您真正要测试的内容。
回答 7
在Python中,none是一个特殊值,通常会指定一个未初始化的变量。要测试A是否不具有此特定值,请使用:
if A is not None
Falsey值是Python中的特殊对象类(例如false,[])。要测试A是否为假,请使用:
if not A
因此,这两个表达式并不相同,您最好不要将它们视为同义词。
PS None也是假的,因此第一个表达式表示第二个表达式。但是第二个覆盖了除None之外的其他虚假值。现在…如果您可以确定除了A中的None以外,不能有其他虚假值,则可以将第二个表达式替换为第一个表达式。
回答 8
这取决于上下文。
我if A:
在希望A
成为某种集合时使用,并且我只想在集合不为空的情况下执行该块。这使调用者可以传递任何行为良好的集合(无论是否为空),并使其按照我的期望进行。它还允许None
和False
禁止执行该块,这有时会方便调用代码。
OTOH,如果我希望A
是一个完全任意的对象,但可能默认将其设置为None
,则我始终使用if A is not None
,因为调用代码可能故意将对空集合,空字符串或0值数字类型的引用传递给它,或者布尔值False
或在布尔上下文中碰巧为false的某个类实例。
另一方面,如果我期望A
是更特定的东西(例如,我要调用其方法的类的实例),但它可能已默认为None
,并且我认为默认布尔转换为我不介意在所有子类上强制执行该类的属性,那么我将使用它if A:
来省掉输入额外12个字符的沉重负担,从而省去了手指的麻烦。
回答 9
我创建了一个名为的文件,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'>
回答 10
前者是Pythonic(更好的意识形态代码),但是如果A为False(不是None),则不会执行该块。
回答 11
python> = 2.6,
如果我们写这样
if A:
将产生警告,
FutureWarning:此方法的行为将在将来的版本中更改。而是使用特定的“ len(elem)”或“ elem不是None”测试。
所以我们可以使用
if A is not None: