在Python 2.7中检查字符串是否为"None"或"not"

7

您是否想知道if not foo is Noneif foo是否相同?使用Python 2.7,foo是一个字符串。


3
@Signal: 不是的。 "if foo is not None" 只检查 foo 是否真正不是单例模式的 "None",而 "if foo" 检查 "if bool(foo)" 或 "if foo.nonzero()",它们是完全不同的事情。 - MSeifert
1
每当字符串的“len”大于0时,“bool(that_string)”返回“True”。如果字符串的“len”为0,则返回“False”。我认为对于像str这样的内置函数,没有“__nonzero__”方法,但我不确定。 - MSeifert
1
我已经上传了我的测试,你可以查看这个gist - MSeifert
1
每个非空变量(如空列表/集合/字典/字符串/...)或0(整数、浮点数、...)或简单的“False”或“None”,在使用“if variable”或“if bool(variable)”时都会被评估为“True”。 - MSeifert
1
我已经更新了我的答案,以进一步解释它。 - MSeifert
显示剩余6条评论
4个回答

11

对于空字符串而言,它们是不同的:

foo = ''
if foo:
    print 'if foo is True'

不会输出任何内容,因为它是空的,因此被视为False,但是:

if foo is not None: 
    print 'if not foo is None is True'

因为 foo 不是 None,所以会打印出来!

我根据 PEP8 进行了修改。 if foo is not None 等同于你的 if not foo is None 但更易读,因此被 PEP8 推荐。


关于 Python 的一般原则的更多介绍:

if a is None:
    pass
if 只有在明确设置了 a = None 的情况下才会为 True
另一方面:
if a:
    pass

有几种方法可用于评估Python中语句的真实性:

  1. Python尝试调用 a.__bool__,如果它被实现,则使用其返回值。

    • 因此,NoneFalse0.00 将求值为 False,因为它们的 __bool__ 方法返回 False
  2. 如果没有实现 a.__bool__,则会检查 a.__len__.__bool__ 返回什么。

    • ''[]set()dict() 等将求值为 False,因为它们的 __len__ 方法返回 0。这是因为 bool(0)False
  3. 如果甚至都没有实现 a.__len__,那么它就返回 True

    • 所以其他所有对象/函数/任何东西都是 True

另请参见:Python文档中的真值测试


1
避免使用“not X is Y”,而是使用“X is not Y”。 - Arĥimedeς ℳontegasppα ℭacilhας
感谢MSeifert,用Python编程中,任何变量(可以是字符串对象和任何其他类型的对象)应该都指向某些东西,对吗?那么 if X is not None 怎么会是 False 呢? - Lin Ma
MSeifert,回答得很好。但是我们怎么知道任何类是否定义了__bool____len__ - Lin Ma
1
help(a) 会显示有关实例的所有信息,或者尝试 print a.__bool__()print a.__len__()(或快捷方式 bool(a), len(a)),看看会引发错误(则未实现)还是是否打印出结果(则已实现)。 - MSeifert
不错的想法,MSeifert,点赞。我经常看到人们写if not X(X可以是任何自定义的类类型)来检查一个对象是否为空,但我没有看到他们是否定义了__bool__len对象?想知道这种写法/方法是否正确?谢谢。 - Lin Ma
1
啊,忘了一个显而易见的情况:如果这两种方法都没有定义,“bool(a)”将返回“True”,无论如何。 - MSeifert

5
不,当foo为空字符串时不一样。
In [1]: foo = ''

In [2]: if foo:
   ...:     print 1
   ...:

In [3]: if foo is None:
   ...:     print 2
   ...:

In [4]: if not foo is None:
   ...:     print 3
   ...:
3

谢谢tianwei,点赞。我经常看到人们写if not X(X可以是任何类型的对象),如果在Python中一个变量必须指向某个对象,那么if not X怎么会是False呢?谢谢。 - Lin Ma
1
@LinMa,当X既不是None也不为空(0、[]、{}、()或''),if not X将会是False。 - tianwei

3

is 运算符比较对象的标识(可以使用 id(something) 检查某个对象的标识)。由于仅有一个 None 实例,因此表达式 something is None 的结果除非是 None is None 或者 something == None ,否则都会返回 False 。运算符 not 优先级低于比较运算符(其中包含 is ),所以对于形如 not string is Nonenot (string is None) 的表达式,结果总是 True

然而,如果字符串不为空,则被视为 True,如果为空字符串,则被视为 False

因此,其中一个表达式的结果始终为 True,而另一个可能会有所变化,所以它们并不等价。


感谢Salva,点赞。我经常看到人们写if not X(X可以是任何类型的对象),如果在Python中一个变量必须指向某个对象,那么if not X怎么可能是False呢?谢谢。 - Lin Ma
1
对于Salva而言,not str is None中的not是作用于str还是作用于str is None?谢谢。 - Lin Ma
1
if not X 可能会是 False,因为在期望布尔值的上下文中,这样的 if 测试会隐式地将 X 转换为布尔值。规定这种转换的规则已在 Python 在线参考手册 中总结。 - Salva
1
@LinMa,回答你的第二个问题时,我意识到了答案推理中的错误。not 的优先级比比较运算符低,因此 not str is None 等同于 not (str is None)。我已经编辑并修复了答案。 - Salva

2
不,尝试这段代码。
foo=''
if foo:
  print (1)
else:
  print (2)
if not foo is None:
  print (3)
else:
  print (4)

它将会打印

2
3

谢谢Sci,点赞。在Python中,任何变量(可以是字符串对象和任何其他类型的对象)都应该指向某个东西,对吗?那么if X is not None怎么会是False呢? - Lin Ma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接