Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果(foo、bar或baz)为无:_Python_Styles_Correctness - Fatal编程技术网

Python 如果(foo、bar或baz)为无:

Python 如果(foo、bar或baz)为无:,python,styles,correctness,Python,Styles,Correctness,我一直在重构一些相当粗糙的代码,遇到了以下相当奇怪的构造: #!/usr/bin/env python2.7 # ... if (opts.foo or opts.bar or opts.baz) is None: # (actual option names changed to protect the guilty) sys.stderr.write("Some error messages that these are required arguments") 。。。我想

我一直在重构一些相当粗糙的代码,遇到了以下相当奇怪的构造:

#!/usr/bin/env python2.7
# ...
if (opts.foo or opts.bar or opts.baz) is None:
    # (actual option names changed to protect the guilty)
    sys.stderr.write("Some error messages that these are required arguments")
。。。我想知道这是否有任何可以想象的意义

我把它改成这样:

#!/usr/bin/env python2.7 
if None in (opts.foo, opts.bar, opts.baz):
    # ...
我确实启动了一个解释器,并实际尝试了第一个构造。。。只有当所有值都为false时,才可以使用,并且这些false值中的最后一个值为None。(换句话说,CPython的实现似乎从表达式链返回第一个真值或最后一个假值)

我仍然怀疑正确的代码应该使用添加了2.5的any()all()内置代码(所讨论的代码已经需要2.7)。我还不确定哪些是首选/预期的语义,因为我刚刚开始这个项目


那么,在任何情况下,这个原始代码都有意义吗?

它的行为是这样的,因为
是一个短路运算符,详细信息见。因此,您的第一个
if
语句等于:

if opts.baz is None

我们可以猜出代码的作者期望的是什么。我认为,正如你所提到的,他想到了使用
而不是全部([opts.foo,opts.bar,opts.baz])
短路行为会导致
foo或bar或baz
返回三个布尔值中的第一个值,如果所有值都是布尔值,则返回最后一个值。所以它的基本意思是“如果所有的都是错的,最后一个是没有的”

您更改的版本略有不同<例如,(opts.foo、opts.bar、opts.baz)中的code>if None
将在
if
块中输入
if
如果
opts.foo
为None,其他两个为1,而原始版本不会(因为
None或1或1
将计算为1,这不是None)。无论其他两个值是什么,当三个值中的任何一个为无时,您的版本将输入
if
,而只有当最后一个值为无且其他两个值为任何布尔假值时,原始版本才会输入
if

您想要这两个版本中的哪一个取决于其余代码的结构以及选项可能采用的值(特别是,它们是否可能具有除无以外的布尔值false,例如
false
0
或空字符串)。从直觉上看,您的版本似乎更合理,但如果代码中有这样的特殊技巧,您永远不知道会出现什么情况。

我更喜欢

 if any(i is None for i in (opts.foo, opts.bar, opts.baz))
因为它准确地表达了预期的目标

奥托

检查错误,而不是
None


原来的代码似乎没有意义;它似乎是由不知道自己在做什么的人编写的。

让我们尝试两种代码:

In [20]: foo = True

In [22]: bar = None

In [23]: baz = None

In [24]: foo or bar or baz
Out[24]: True

In [25]: (foo or bar or baz) is None
Out[25]: False

In [28]: ((foo or bar or baz) is None) == (None in (foo, bar, baz))
Out[28]: False
您可以看到您的重写与原始代码不同

第一个条件仅在所有变量均为“无”时返回True

In [19]: (None or None or None) is None
Out[19]: True
因此,您可以将第一个条件重写为:

if foo == bar == bar == None:

更具体地回答他的问题:代码似乎确实出错了,我想不出哪种情况是有意义的。如果没有“is”操作符,这是有意义的。但从技术上来说,这是测试所有值是否都为false,最后一个值是对None单例的引用,这太糟糕了。注意不要通过修复此错误引入新的bug:)我承认语义不同;这里的要点是推测原始语义是否有任何合理的情况是正确的。我认为前面的代码在各种情况下都会失败,令人高兴的是,在实践中似乎从未注意到。(它是内部命令行实用程序的一部分,只有极少数工作人员使用过)。
if foo == bar == bar == None: