Python `if x is not None` 或 `if not x is None`?[关闭]
- 2025-04-15 09:20:00
- admin 原创
- 31
问题描述:
我一直认为if not x is None
版本更清晰,但谷歌的风格指南和PEP-8都使用了if x is not None
。它们之间是否存在细微的性能差异(我假设没有),以及是否存在一种情况,其中一种确实不适合(这使得另一种明显更符合我的惯例)?*
*我指的是任何单身人士,而不仅仅是None
。
...比较像 None 这样的单例。使用 is 或 is not。
解决方案 1:
由于它们编译为相同的字节码,因此没有性能差异:
>>> import dis
>>> dis.dis("not x is None")
1 0 LOAD_NAME 0 (x)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
>>> dis.dis("x is not None")
1 0 LOAD_NAME 0 (x)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
从文体上来说,我尽量避免使用not x is y
,因为人类读者可能会误解为(not x) is y
。如果我x is not y
这样写,就不会产生歧义。
解决方案 2:
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
。:]
解决方案 3:
代码首先应该让程序员理解,其次才是让编译器或解释器理解。“is not”的结构比“not is”更接近英语。
解决方案 4:
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 是同一个对象时才为真。x is not y
产生逆真值。
Python语法is not
中专门提供了以下功能,以提高语言的可读性:
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
。
不使用它是不明智的。
解决方案 5:
答案比人们想象的要简单。
两种方式都没有任何技术优势,而且“x is not y”是每个人都会使用的,这使得它成为明显的赢家。它是否“更像英语”并不重要;每个人都在使用它,这意味着每个 Python 用户——即使是 Python 看起来和英语完全不一样的中国用户——都能一眼看懂,而那些不太常见的语法则需要额外的脑力劳动来解析。
不要为了与众不同而与众不同,至少在这个领域不要这样做。
解决方案 6:
我个人使用
if not (x is None):
每个程序员,甚至那些不熟悉 Python 语法的程序员,都可以立即理解这一点,没有任何歧义。
解决方案 7:
出于风格原因,运算符比否定的结果更受欢迎。“ ”is not
读起来就像英语,但“ ”需要理解运算符的优先级,并且读起来不像英语。is
`if x is not None:`if not x is None:
如果存在性能差异,我更倾向于is not
,但这几乎肯定不是选择该技术的动机。它显然依赖于具体实现。由于is
不可覆盖,因此应该很容易通过优化消除任何差异。
解决方案 8:
if not x is None
与其他编程语言更相似,但if x is not None
对我来说听起来更清晰(并且在英语语法上更正确)。
话虽如此,但对我来说这似乎更像是一种偏好问题。
解决方案 9:
我更喜欢更具可读性的形式,x is not y
而不是思考如何最终编写运算符的代码处理优先级,以便生成更具可读性的代码。
扫码咨询,免费领取项目管理大礼包!