Python如果x不是None或者如果不是x就是None?
我一直认为, if not x is None
版本更清晰,但if x is not None
,Google的风格指南和PEP-8都会使用。 是否有任何微小的performance差异(我假设不),是否有任何情况下,一个真的不适合(使另一个明显的赢家我的约定)?
*我指的是任何单身人士,而不是None
。
比较单例如None。 使用是或不是。
没有性能差异,因为它们编译为相同的字节码:
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
。 尽pipe编译器总是把它看作not (x is y)
,但是人类读者可能会误解这个构造为(not x) is y
。 如果我写x is not y
那么没有歧义。
代码首先应该写成对程序员来说是可以理解的,而编译器或者翻译器则应该是可以理解的。 “不是”构造比“不是”更接近英语。
Google和Python的风格指南都是最好的做法:
if x is not None: # Do something about x
not 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
:
- 真值testing
编辑下面的评论:
我只是做了更多的testing。 not x
是没有先不否定x
,然后比较None
。 实际上,运算符在使用这种方式时似乎具有更高的优先级:
>>> x [0] >>> not x is None True >>> not (x is None) True >>> (not x) is None False
所以, not x is None
,就我个人的意见而言,最好避免。
更多编辑:
我只是做了更多的testing,可以确认bukzor的评论是正确的。 (至less,我不能certificate这一点。)
这意味着if x is not None
确切的结果, if not x is None
。 我纠正了。 感谢bukzor。
但是,我的答案仍然是: 使用常规if x is not None
。 :]
答案比人们做得更简单。
没有任何技术上的优势,“x不是y”就是其他人使用的 ,这使得它成为了赢家。 不要紧,它“看起来更像英语”或不是; 每个人都使用它,这意味着Python的每一个用户,即使是中文用户,其语言Python看起来都不像 – 一眼就能理解,稍微不太常见的语法将需要一些额外的大脑周期来parsing。
至less在这个领域,不要为了不同而有所不同。
if x is not None
或者if not x is None
Python?
TLDR:字节码编译器将它们parsing为x is not None
– 为了可读性, if x is not None
,则使用。
可读性
我们使用Python是因为我们重视诸如人的可读性,可用性和编程相对于性能的各种范式的正确性。
Python优化可读性,特别是在这种情况下。
parsing和编译字节码
not
比is
更弱 ,所以这里没有逻辑上的区别。 请参阅文档 :
运算符
is
,is not
testing对象的身份:当且仅当x和y是同一个对象时,x is y
是真的。x is not y
产生逆真值。
在Python 语法中 is not
特别提供这种语言的可读性改进:
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
所以它也是语法的一个单一元素。
当然,它不是parsing相同的:
>>> 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
。
不使用它是不明智的。
这is not
运营商是优于否定的结果is
为了文体的原因。 “ if x is not None:
”就像英文一样,但是“ if not x is None:
”,则需要了解运算符优先级,而不是像英文一样阅读。
如果我的资金存在绩效差异的话,那么这个决定并不是这个技术的动机。 这显然是依赖于实现的。 既然is
不可覆盖的,那么无论如何应该很容易优化任何区别。
if not x is None
与其他编程语言更为相似,但if x is not None
, if x is not None
对于我来说,无疑肯定听起来更清晰(而且在语法上更为正确)。
这就是说,它似乎是对我更喜欢的东西。
我个人使用
if not (x is None):
即使那些不熟悉Python语法的程序员也能毫不含糊地理解它。
我宁愿更可读的formsx is not y
比我想如何最终编写操作符的代码处理优先级,以便产生更多的可读代码。
尝试这个:
if x != None: # do stuff with x
x = None if not x: print x, '2.?'
没有2.?
from __future__ import print_function if(not x): print(x, '3.?')
(无,“3.?”)