不是 Python 中的无测试 [重复]
Posted
技术标签:
【中文标题】不是 Python 中的无测试 [重复]【英文标题】:not None test in Python [duplicate] 【发布时间】:2011-04-27 06:40:38 【问题描述】:在这些非无测试中。
if val != None:
if not (val is None):
if val is not None:
哪个更好,为什么?
【问题讨论】:
if val:
怎么样?
那不是同一个测试!如果 val 为 0、""、[]、0.0,则 if
将为 false。等等,如果它是无。
【参考方案1】:
if val is not None:
# ...
是用于测试变量未设置为None
的Pythonic 习惯用法。这个成语在declaring keyword functions with default parameters 的情况下有特殊用途。 is
在 Python 中测试身份。因为在运行的 Python 脚本/程序中存在一个且只有一个 None
实例,所以 is
是对此的最佳测试。作为Johnsyweb points out,这在PEP 8 的“编程建议”下进行了讨论。
至于为什么首选这个
if not (val is None):
# ...
这只是Zen of Python 的一部分:“可读性很重要。”好的 Python 往往接近于好的 pseudocode。
【讨论】:
另外,“is not”具有为此目的创建的特殊语义(这不是表达式构造的逻辑结果;“1 is (not None)”和“1 is not None”有两个不同的结果。 "not None" 返回 True。很有趣。 @gotgenes 并不总是正确的。例如:var = ''。如果您运行此代码,它将成功测试无。因此,您无法测试变量是否设置为 None 或空字符串。 @Ethanval = ''; print(val is not None)
打印出True
,那么你发现哪一部分不正确?
至于为什么不推荐val != None
:如果val
可以是None
或更复杂的东西,比如一个numpy 数组,这是否打算成为一个尚不完全清楚逐元素比较(例如:arr>0
将生成 arr 元素为正的索引列表),因此如果您希望 val
是数组或 None
,那么 arr is None
是最安全的方法来测试一下。事实上,Python 2.7.6 会生成一个警告,指出 arr != None
将来会按元素工作。 arr is not None
也更易于阅读。【参考方案2】:
来自,编程建议,PEP 8:
应始终使用
is
或is not
与诸如 None 之类的单例进行比较,而不应使用相等运算符。另外,当您真正的意思是
if x is not None
时,请注意不要写if x
- 例如。在测试默认为 None 的变量或参数是否设置为其他值时。另一个值可能具有在布尔上下文中可能为 false 的类型(例如容器)!
PEP 8 是任何 Python 程序员的必备读物。
【讨论】:
【参考方案3】:这类问题的最佳选择是确切了解 python 的作用。 dis
模块提供了令人难以置信的信息:
>>> import dis
>>> dis.dis("val != None")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 3 (!=)
6 RETURN_VALUE
>>> dis.dis("not (val is None)")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
>>> dis.dis("val is not None")
1 0 LOAD_NAME 0 (val)
2 LOAD_CONST 0 (None)
4 COMPARE_OP 9 (is not)
6 RETURN_VALUE
请注意,最后两种情况简化为相同的操作序列,Python 读取not (val is None)
并使用is not
operator。与None
比较时,第一个使用!=
operator。
正如其他答案所指出的,在与None
进行比较时使用!=
是一个坏主意。
【讨论】:
compare_op 9 和 3 有什么区别? @evolvedmicrobe 从dis doc
(https://docs.python.org/3/library/dis.html),COMPARE_OP
执行对应元组dis.cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is not', 'exception match', 'BAD')
的布尔运算。所以COMPARE_OP 9
执行is not
和COMPARE_OP 3
执行!=
。【参考方案4】:
后两者中的任何一个,因为val
可能属于定义__eq__()
以在传递None
时返回true 的类型。
【讨论】:
这是相当卑鄙的__eq__()
行为,我没有考虑过。捕捉角落案例的好答案。以上是关于不是 Python 中的无测试 [重复]的主要内容,如果未能解决你的问题,请参考以下文章