在Python中我应该如何测试变量是否为None,True或False

问题:在Python中我应该如何测试变量是否为None,True或False

我有一个可以返回以下三项之一的函数:

  • 成功(True
  • 失败(False
  • 错误读取/解析流(None

我的问题是,如果不应该针对True或进行测试False,应该如何查看结果。以下是我目前的操作方式:

result = simulate(open("myfile"))
if result == None:
    print "error parsing stream"
elif result == True: # shouldn't do this
    print "result pass"
else:
    print "result fail"

它真的像删除== True零件一样简单,还是应该添加一个三布尔数据类型。我不希望该simulate函数引发异常,因为我希望外部程序对错误进行的所有操作均将其记录并继续。

I have a function that can return one of three things:

  • success (True)
  • failure (False)
  • error reading/parsing stream (None)

My question is, if I’m not supposed to test against True or False, how should I see what the result is. Below is how I’m currently doing it:

result = simulate(open("myfile"))
if result == None:
    print "error parsing stream"
elif result == True: # shouldn't do this
    print "result pass"
else:
    print "result fail"

is it really as simple as removing the == True part or should I add a tri-bool data-type. I do not want the simulate function to throw an exception as all I want the outer program to do with an error is log it and continue.


回答 0

不要害怕exceptions!让您的程序仅记录并继续操作很容易:

try:
    result = simulate(open("myfile"))
except SimulationException as sim_exc:
    print "error parsing stream", sim_exc
else:
    if result:
        print "result pass"
    else:
        print "result fail"

# execution continues from here, regardless of exception or not

现在,如果您发现错误/没有错误的信息不足,那么您可以从模拟方法中获得更丰富的通知类型,以了解确切的错误原因。

Don’t fear the Exception! Having your program just log and continue is as easy as:

try:
    result = simulate(open("myfile"))
except SimulationException as sim_exc:
    print "error parsing stream", sim_exc
else:
    if result:
        print "result pass"
    else:
        print "result fail"

# execution continues from here, regardless of exception or not

And now you can have a much richer type of notification from the simulate method as to what exactly went wrong, in case you find error/no-error not to be informative enough.


回答 1

if result is None:
    print "error parsing stream"
elif result:
    print "result pass"
else:
    print "result fail"

保持简单明了。您当然可以预定义字典。

messages = {None: 'error', True: 'pass', False: 'fail'}
print messages[result]

如果您打算修改simulate函数以包含更多的返回代码,则维护此代码可能会有点问题。

simulate还可以在解析错误引发异常,在这种情况下,你要么就在这里抓住它还是让它传播水平并打印位将减少到单行if-else语句。

if result is None:
    print "error parsing stream"
elif result:
    print "result pass"
else:
    print "result fail"

keep it simple and explicit. You can of course pre-define a dictionary.

messages = {None: 'error', True: 'pass', False: 'fail'}
print messages[result]

If you plan on modifying your simulate function to include more return codes, maintaining this code might become a bit of an issue.

The simulate might also raise an exception on the parsing error, in which case you’d either would catch it here or let it propagate a level up and the printing bit would be reduced to a one-line if-else statement.


回答 2

从来没有,从来没有说过

if something == True:

决不。这太疯狂了,因为您要重复地重复为if语句重复指定为冗余条件规则的内容。

更糟糕的是,仍然,永远,永远,永远不要说

if something == False:

你有not。随意使用它。

最后,这样做a == None效率低下。做a is NoneNone是一个特殊的单例对象,只能有一个。只需检查看看是否有该对象。

Never, never, never say

if something == True:

Never. It’s crazy, since you’re redundantly repeating what is redundantly specified as the redundant condition rule for an if-statement.

Worse, still, never, never, never say

if something == False:

You have not. Feel free to use it.

Finally, doing a == None is inefficient. Do a is None. None is a special singleton object, there can only be one. Just check to see if you have that object.


回答 3

我想强调的是,即使身在何处的情况下if expr :,因为一个要确保不充分exprTrue,不只是从不同0/ None/不管,is是从者优先== 由于同样的原因美国洛特mentionned避免== None

确实,它效率更高,而且蛋糕上的樱桃更易被人阅读。

In [1]: %timeit (1 == 1) == True
38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit (1 == 1) is True
33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

I would like to stress that, even if there are situations where if expr : isn’t sufficient because one wants to make sure expr is True and not just different from 0/None/whatever, is is to be prefered from == for the same reason S.Lott mentionned for avoiding == None.

It is indeed slightly more efficient and, cherry on the cake, more human readable.

In [1]: %timeit (1 == 1) == True
38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit (1 == 1) is True
33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

回答 4

我认为抛出异常对您的情况更好。一种替代方法是返回元组的模拟方法。第一项是状态,第二项是结果:

result = simulate(open("myfile"))
if not result[0]:
  print "error parsing stream"
else:
  ret= result[1]

I believe that throwing an exception is a better idea for your situation. An alternative will be the simulation method to return a tuple. The first item will be the status and the second one the result:

result = simulate(open("myfile"))
if not result[0]:
  print "error parsing stream"
else:
  ret= result[1]