用'is'替换'=='来比较布尔值是否安全

kev*_*kev 46 python

我做了几个布尔比较:

>>> (True or False) is True
True
>>> (True or False) == True
True
Run Code Online (Sandbox Code Playgroud)

这听起来像==is是布尔值互换.

有时使用起来更清楚 is

我想知道:

TrueFalsepython中预分配?

bool(var)始终返回相同True(或False与预分配)True(或False)?

它是安全的替代==is比较布尔值?


这不是最佳实践.

我只是想知道真相.

det*_*tly 57

你可能不需要比较布尔值.如果你做的事情如下:

if some_bool == True:
  ...
Run Code Online (Sandbox Code Playgroud)

......只需将其更改为:

if some_bool:
  ...
Run Code Online (Sandbox Code Playgroud)

没有is==需要.

正如评论者指出的那样,有正当理由来比较布尔值.如果两个布尔都是未知的并且你想知道一个是否等于另一个,你应该使用==or !=而不是isor is not(原因在下面解释).请注意,这在逻辑上等效于,xnor并且xor在Python中不作为逻辑运算符存在.

在内部,应该永远只能是两个布尔字面对象(另见C API),并且bool(x) is True应该是True,如果bool(x) == True任何Python程序.两个警告:

  • 并不意味着x is True,如果x == True,但是(例如x = 1).
  • 这适用于Python(CPython)的常规实现,但在其他实现中可能不适用.因此==是一种更可靠的比较.

  • @Matthew @detly:对不起,经过反思,我不应该投票,而只是留下评论.似乎大多数人都想象"True == True"作为"<my expression> == True"的替身,在这种情况下我们应该按照建议编写"<my expression>".但这错过了(在我看来很明显)"True == True"实际上是"<我的第一个表达式> == <我的第二个表达式>"的替身,这是一个非常有效的写法.我无法撤消我的downvote.不过我还是觉得原来(未经编辑)的答案很糟糕. (5认同)
  • 在某些情况下,您需要比较布尔值,例如当比较时布尔值未知时。当您将布尔值解释为更像信息位而不是真值并且与异或运算符“^”完全一样有效时,这种需求很容易出现。 (2认同)
  • 您可能想比较布尔值的一种情况是Django的BooleanField,其值可能为None。对于具有字段my_bool的名为my_model的模型,无论字段值是False还是None,语句“ if not my_model.my_bool”将执行,如果语句读取“ if my_model”则不会发生。 my_bool == False`。有点明显,与所有方案都不相关,但值得考虑。 (2认同)

kev*_*pie 36

留意你可能会比较的其他内容.

>>> 1 == True
True
>>> 1 is True
False
Run Code Online (Sandbox Code Playgroud)

True和False将在python实例中为其生命周期提供稳定的对象ID.

>>> id(True)
4296106928
>>> id(True)
4296106928
Run Code Online (Sandbox Code Playgroud)

is 比较对象的id

编辑:添加 or

由于OP正在使用or中,因此可能值得指出这一点.

或者评估为True:返回第一个'True'对象.

>>> 1 or True
1
>>> 'a' or True
'a'
>>> True or 1
True
Run Code Online (Sandbox Code Playgroud)

或者评估False:返回最后一个'False'对象

>>> False or ''
''
>>> '' or False
False
Run Code Online (Sandbox Code Playgroud)

并且计算结果为True:返回最后一个'True'对象

>>> True and 1
1
>>> 1 and True
True
Run Code Online (Sandbox Code Playgroud)

并且计算结果为False:返回第一个'False'对象

>>> '' and False
''
>>> False and ''
False
Run Code Online (Sandbox Code Playgroud)

这是一个重要的python习惯用法,它允许简洁而紧凑的代码来处理常规python对象上的布尔逻辑.

>>> bool([])
False
>>> bool([0])
True
>>> bool({})
False
>>> bool({False: False})
True
>>> bool(0)
False
>>> bool(-1)
True
>>> bool('False')
True
>>> bool('')
False
Run Code Online (Sandbox Code Playgroud)

基本上'空'对象是假的,'非空'是真的.

将其与@ detly和其他答案相结合,可以提供一些有关如何if在python中使用和bool的见解.

  • 对.`bool(1)==> True`所以`bool(1)是True ==> True`.当您必须具有相同的对象实例时,应使用****. (2认同)

Mat*_*hen 5

是.有保证的是正好有两个boolS,真假:

类bool不能进一步子类化.它唯一的例子是假和真.

这意味着,如果你知道两个操作数都是bool,==而且is是等价的.但是,正如det det地说,在这种情况下通常没有理由使用.


小智 5

似乎所有答案都涉及解释器启动后定义的True和。False在布尔值成为 Python 的一部分之前,它们通常被定义为程序的一部分。即使现在(Python 2.6.6)它们也只是可以指向不同对象的名称:

>>> True = 1
>>> (2 > 1)
True
>>> (2 > 1) == True
True
>>> (2 > 1) is True
False
Run Code Online (Sandbox Code Playgroud)

如果您必须处理较旧的软件,请注意这一点。