在Python中没有测试

时间:2010-10-19 03:20:19

标签: python nonetype

这些不是无测试。

if val != None:

if not (val is None):

if val is not None:

哪一个更好,为什么?

4 个答案:

答案 0 :(得分:834)

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

答案 1 :(得分:94)

From,Programming Recommendations,PEP 8

  

应该总是与像None这样的单身人士进行比较   '是'或'不是',绝不是平等运营商。

     

另外,当你的意思是“如果x不是无”时,要小心写“if x”    - 例如在测试默认的变量或参数时   没有设置为其他值。另一个值可能有一个类型   (例如容器)在布尔上下文中可能为false!

PEP 8是任何Python程序员必读的。

答案 2 :(得分:21)

后两者中的任何一个,因为val可能是一种类型,定义__eq__()在传递None时返回true。

答案 3 :(得分:15)

这些类型问题的最佳选择是确切了解python的功能。 dis模块非常有用:

>>> def f(val):
...   if val != None:
...     return True
...   return False
...
>>> def g(val):
...   if not (val is None):
...     return True
...   return False
...
>>> def h(val):
...   if val is not None:
...     return True
...   return False
...
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               3 (!=)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE
>>> dis.dis(h)
  2           0 LOAD_FAST                0 (val)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 POP_JUMP_IF_FALSE       16

  3          12 LOAD_GLOBAL              1 (True)
             15 RETURN_VALUE

  4     >>   16 LOAD_GLOBAL              2 (False)
             19 RETURN_VALUE

请注意,最后两种情况会减少到相同的操作序列(python读取not (val is None)并使用is not运算符)。第一个使用!=运算符与None进行比较。

正如其他答案所指出的,在与None比较时使用!=是一个坏主意