当my_var
可以是无?
if my_var and 'something' in my_var:
#do something
问题是如果my_var为None,'something' in my_var
将抛出TypeError。
或者我应该使用:
if my_var:
if 'something' in my_var:
#do something
或
try:
if 'something' in my_var:
#do something
except TypeError:
pass
重新解释一下这个问题,上面哪一项是Python中的最佳实践(如果有的话)?
欢迎替代方案!
答案 0 :(得分:81)
依赖于条件(Python reference here)的顺序是安全的,特别是因为你指出的问题 - 能够短路评估可能会导致一系列条件问题非常有用。
这种代码以大多数语言弹出:
IF exists(variable) AND variable.doSomething()
THEN ...
答案 1 :(得分:31)
是的,它是安全的,它在语言参考中明确且非常明确地定义:
表达式
x and y
首先进行评估x
;如果x
为false
,则其值为 回;否则,评估y
并返回结果值。表达式
x or y
首先进行评估x
;如果x
为真,则其值为 回;否则,评估y
并返回结果值。
答案 2 :(得分:2)
我可能在这里有点迂腐,但我会说最好的答案是
if my_var is not None and 'something' in my_var:
#do something
区别在于None
的显式检查,而不是my_var
到True
或False
的隐式转换。
虽然我确信在您的情况下区别并不重要,但在更一般的情况下,变量很可能不是None
但仍然评估为False
,例如,0
的整数值或空列表。
与大多数其他海报的断言相反,它是安全的,我会说只要你是明确的,它就是安全的。如果你不相信,那么请考虑这个非常有人工作的课程:
class Contrived(object):
def __contains__(self, s):
return True
def __nonzero__(self):
return False
my_var = Contrived()
if 'something' in my_var:
print "Yes the condition is true"
if my_var and 'something' in my_var:
print "But this statement won't get reached."
if my_var is not None and 'something' in my_var:
print "Whereas this one will."
是的我知道这不是一个现实的例子,但实际代码确实会发生变化,尤其是当None
用于表示默认函数参数时。
答案 3 :(得分:1)
这是非常安全的,我一直这样做。
答案 4 :(得分:1)
我会选择try / except,但这取决于你对变量的了解。
如果您希望变量在大多数时间都存在,那么try / except就是较少的操作。如果您希望变量在大多数情况下都是None,那么IF语句将减少操作。
答案 5 :(得分:1)
这不是那么简单。作为C#dude,我非常习惯于这样做:
if(x != null && ! string.isnullorempty(x.Name))
{
//do something
}
以上效果很好,并按预期进行评估。但是在VB.Net中,以下内容会产生您不期望的结果:
If Not x Is Nothing **And** Not String.IsNullOrEmpty(x.Name) Then
'do something
End If
以上将产生异常。正确的语法应该是
If Not x Is Nothing **AndAlso** Not String.IsNullOrEmpty(x.Name) Then
'do something
End If
请注意非常微妙的区别。这让我困惑了大约10分钟(太长时间了),这就是为什么C#(和其他)家伙在用其他语言编写代码时需要非常小心。