在Python中没有测试

pro*_*eek 636 python nonetype

这些不是无测试.

if val != None:

if not (val is None):

if val is not None:
Run Code Online (Sandbox Code Playgroud)

哪个更好,为什么?

got*_*nes 918

if val is not None:
    # ...
Run Code Online (Sandbox Code Playgroud)

是用于测试变量未设置的Pythonic习语None.在使用默认参数声明关键字函数的情况下,此惯用法具有特殊用途.is在Python中测试身份.因为None在运行的Python脚本/程序中只存在一个且只有一个实例,所以这是is最佳测试.正如Johnsyweb指出的那样,这将在PEP 8的 "编程建议"中进行讨论.

至于为什么这是优选的

if not (val is None):
    # ...
Run Code Online (Sandbox Code Playgroud)

这只是Python禅宗的一部分:"可读性很重要." 好的Python通常接近良好的伪代码.

  • 另外,"不是"有为此目的而创建的特殊semeantics(它不是​​构造表达式的逻辑结果;"1是(不是None)"和"1不是None"有两种不同的结果. (50认同)
  • “非无”返回真。有趣的。 (2认同)
  • @Ethan`val =''; print(val不是None)`打印`True`,那么你发现哪个部分不正确? (2认同)
  • 至于为什么不建议使用``val!= None``:如果``val``可以是``None``或更复杂的东西,比如numpy数组,那么这是否打算是一个逐元素的比较(例如:``arr> 0``将产生一个arr元素为正的索引列表),所以如果你希望``val``是一个数组或``None``那么``arr is None``是测试这个的最安全的方法.实际上,Python 2.7.6会生成一个警告,"arr!= None``将在未来以元素方式工作.``arr is not None``也更好读. (2认同)

Joh*_*web 101

来自,编程建议,PEP 8:

像None这样的单例的比较应该总是用'is'或'is not'来完成,而不是等于运算符.

此外,当你真正意味着"如果x不是无"时,请注意写"if x" - 例如,在测试默认为None的变量或参数是否设置为其他值时.另一个值可能有一个类型(如容器)在布尔上下文中可能为false!

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


Ign*_*ams 22

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

  • 这是相当卑鄙的`__eq __()`行为,而我还没有考虑过.抓住角落案件的好答案. (4认同)

She*_*tJS 20

这些类型问题的最佳选择是确切了解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
Run Code Online (Sandbox Code Playgroud)

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

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

  • @evolvedmicrobe 来自`dis doc` ([https://docs.python.org/3/library/dis.html](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` 执行`!=`。 (2认同)