问题:Python的`如果x不是None`或`如果x不是None`?
我一直认为该if not x is None
版本会更清晰,但是Google的样式指南和PEP-8都使用if x is not None
。是否存在任何微小的性能差异(我假设不是),并且在任何情况下确实不适合(使另一方成为我的会议的明显获胜者)吗?*
*我指的是任何单身人士,而不仅仅是None
。
…比较单例,如“无”。使用是或不是。
回答 0
没有性能差异,因为它们可以编译为相同的字节码:
Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
... return x is not None
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
>>> def g(x):
... return not x is None
...
>>> dis.dis(g)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 0 (None)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
从风格上讲,我尽量避免not x is y
。尽管编译器总是将其视为not (x is y)
。读者可能会误解为(not x) is y
。如果我写的x is not y
话就没有歧义。
回答 1
Google和Python的样式指南都是最佳做法:
if x is not None:
# Do something about x
使用not x
会导致不良结果。
见下文:
>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0] # You don't want to fall in this one.
>>> not x
False
您可能有兴趣了解对Python True
或False
在Python 中评估了哪些文字:
编辑以下评论:
我只是做了一些测试。先not x is None
不取反x
,然后与相比较None
。实际上,is
使用这种方式时,似乎运算符具有更高的优先级:
>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False
因此,not x is None
以我的诚实观点,最好避免。
更多编辑:
我只是做了更多测试,可以确认bukzor的评论正确。(至少,我无法证明这一点。)
这意味着if x is not None
结果与相同if not x is None
。我站得住了。谢谢布克佐。
但是,我的答案仍然是:使用常规if x is not None
。:]
回答 2
应该首先编写代码,以便程序员首先可以理解,然后再编译器或解释器理解。“不是”构造比“不是”更像英语。
回答 3
Python
if x is not None
还是if not x is None
?
TLDR:字节码编译器将它们都解析为x is not None
-为了便于阅读,请使用if x is not None
。
可读性
我们之所以使用Python,是因为我们重视诸如人类可读性,可用性和各种编程范式的正确性之类的东西,而不是性能。
Python针对可读性进行了优化,尤其是在这种情况下。
解析和编译字节码
的not
结合更弱比is
,所以这里没有逻辑的差异。请参阅文档:
运算符
is
并is not
测试对象标识:x is y
当且仅当x和y是同一对象时才为true。x is not y
产生反真值。
将is not
有具体规定,在Python 语法作为语言可读性改善:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
因此,它也是语法的一个统一要素。
当然,它的解析方式不同:
>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"
但是字节编译器实际上会将转换not ... is
为is not
:
>>> import dis
>>> dis.dis(lambda x, y: x is not y)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 COMPARE_OP 9 (is not)
9 RETURN_VALUE
因此,为了便于阅读并按预期使用语言,请使用is not
。
不使用它是不明智的。
回答 4
答案比人们做的要简单。
两种方法都没有技术优势,其他人都使用 “ x不是y” ,这显然是赢家。是否“看起来更像英语”并不重要;每个人都使用它,这意味着Python的每个用户-甚至是中国用户,其语言与Python看起来都不像-都将一目了然地理解它,稍稍不常见的语法将需要花费更多的脑力来解析。
至少在这个领域,不要仅仅为了与众不同而与众不同。
回答 5
is not
由于is
风格上的原因,操作员优先于否定结果。“ if x is not None:
”的读法类似于英语,但“ if not x is None:
”需要理解操作符的优先级,并且读起来并不像英文。
如果有性能上的差异,我会花钱is not
,但这几乎肯定不是决定选择该技术的动机。显然,这将取决于实现。由于这is
是不可替代的,因此无论如何都应该很容易优化任何区别。
回答 6
我个人使用
if not (x is None):
每个程序员,即使不是Python语法专家的程序员,也都可以毫不歧义地立即理解它。
回答 7
if not x is None
与其他编程语言更相似,但if x is not None
对我来说绝对听起来更清晰(英语语法更正确)。
话虽如此,这似乎对我来说更偏爱。
回答 8
我更喜欢可读性强的形式,而x is not y
不是想如何最终写出运算符的代码处理优先级以产生可读性更高的代码。