我一直认为if not x is None
版本更清晰,但Google的style guide和PEP-8都使用if x is not None
。是否有任何轻微的性能差异(我假设没有),并且是否有任何一个真正不合适的情况(使另一个成为我的会议的明显赢家)?*
*我指的是任何单身人士,而不仅仅是None
。
...比较单身人士 没有。使用是否。
答案 0 :(得分:875)
没有性能差异,因为它们编译为相同的字节码:
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 :(得分:152)
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
:
编辑以下评论:
我刚做了一些测试。 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
。我纠正了。谢谢bukzor。
但是,我的回答仍然存在:使用传统的if x is not None
。 :]
答案 2 :(得分:119)
代码应该首先编写为程序员可以理解,然后编译器或解释器编写。 “不是”构造比“不是”更接近英语。
答案 3 :(得分:29)
答案比人们做的简单。
无论哪种方式都没有技术优势,“x不是y”是其他人使用的,这使它成为明显的赢家。它“看起来更像英语”并不重要;每个人都使用它,这意味着Python的每个用户 - 甚至是中文用户,他们的语言Python看起来都不像 - 会一目了然地理解它,其中稍微不那么常见的语法将花费几个额外的脑循环来解析。
不要只是为了与众不同,至少在这个领域是不同的。
答案 4 :(得分:23)
Python
if x is not None
或if not x is None
?
TLDR:字节码编译器将它们解析为x is not None
- 所以为了便于阅读,请使用if x is not None
。
我们使用Python是因为我们重视人的可读性,可用性以及各种编程范式的正确性。
Python优化了可读性,尤其是在此上下文中。
not
binds more weakly比is
,所以这里没有逻辑差异。请参阅documentation:
运算符
is
和is not
测试对象标识:x is y
为真 当且仅当x和y是同一个对象时。x is not y
产生了 反向真值。
is not
专门为Python grammar提供了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
因此,为了便于阅读和使用预期的语言,请使用module.exports = function (one, two, callback) {
var fs = require("fs");
var path = require("path");
var konc = "." + two;
fs.readdir(one, function (err, list) {
if (err) return callback(err);
var list = list.filter(function (x) {
return path.extname(x) == konc;
});
callback(null, list)
})
}
。
不使用 不是 明智。
答案 5 :(得分:9)
由于样式原因,is not
运算符优先于否定is
的结果。 “if x is not None:
”的读取方式与英语类似,但“if not x is None:
”需要了解运算符优先级,并且不会像英语一样阅读。
如果存在绩效差异,我的资金就在is not
,但这几乎肯定不是决定更喜欢这种技术的动机。它显然是依赖于实现的。由于is
不可覆盖,因此无论如何都应该很容易优化任何区别。
答案 6 :(得分:6)
就个人而言,我使用
if not (x is None):
每个程序员都会毫不含糊地理解,即使是那些不熟悉Python语法的程序员。
答案 7 :(得分:1)
if not x is None
与其他编程语言更相似,但if x is not None
对我来说肯定听起来更清晰(在语法上更正确)。
那说对我来说这似乎更像是一种偏爱。
答案 8 :(得分:0)
我更喜欢更易读的形式x is not y
我认为如何最终编写运算符的代码处理优先级,以产生更易读的代码。
答案 9 :(得分:-4)
试试这个:
if x != None:
# do stuff with x