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中将哪些文字评估为TrueFalse

  • 真值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和编译字节码

notis 更弱 ,所以这里没有逻辑上的区别。 请参阅文档 :

运算符isis nottesting对象的身份:当且仅当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 Noneif 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.?”)