为什么分配给True / False不能像我期望的那样工作?

时间:2010-01-13 07:12:48

标签: python python-2.x

作为回答另一个问题的一部分,我写了下面的代码,其行为乍一看似乎很奇怪:

print True                    # outputs true
True = False;    print True   # outputs false
True = True;     print True   # outputs false
True = not True; print True   # outputs true

任何人都可以解释这种奇怪的行为吗?我认为它与Python的对象模型有关,但我不确定。

它是Cygwin下的2.5.2版本。

5 个答案:

答案 0 :(得分:75)

Python有这两个(以及其他)内置对象。它们只是物体;在开始时,它们还没有任何名称,但要知道我们所指的是什么,我们称之为0x600D0xBAD

在开始执行Python(2.x)脚本之前,名称True绑定到对象0x600D,名称False绑定到对象{{1因此,当程序引用0xBAD时,它会查看True

由于0x600D0x600D知道它们通常由名称0xBADTrue使用,因此它们在打印时会输出,即{{1} } False的方法返回__str__等等。

0x600D

现在将名称'True'绑定到另一个对象。从现在开始,名称True = False True都引用同一个对象True,在打印时会输出False

0xBAD

实际上没有做任何事情:它接受名称False引用的对象,并将新(和旧)名称True = True 绑定到此对象。由于(由于上一步骤)True在此之前引用True,因此在此之后仍然引用True。因此,打印仍然会输出0xBAD

0xBAD

首先获取名称False绑定的对象,即True = not True 。它将此对象提供给True运算符。 0xBAD不关心(或知道)此处使用的名称来引用not,它只知道在给定not时它应该返回0xBAD。然后将此返回值赋给赋值运算符0xBAD,将名称0x600D绑定到此对象。

由于名称=现在再一次引用对象True,因此调用True输出0x600D,世界再次变好。

答案 1 :(得分:43)

想象一下:

A = True
B = False

print A           # true
A = B;  print A   # false
A = A;  print A   # false, because A is still false from before
A = not A; print A # true, because A was false, so not A is true

同样的事情正在发生,但在你的版本中它令人困惑,因为你不期望你可以重新定义真与假。

答案 2 :(得分:18)

在2.x中,True和False不是关键字,所以可以用这种方式遮蔽内置函数。

答案 3 :(得分:12)

您可以检查True / False是否为关键字:

>>> import keyword
>>> keyword.iskeyword('True')
False

由于它不是(在我的版本中),分配True = False只是意味着“True”是另一个“变量”名称。

答案 4 :(得分:0)

您可以使用简单的布尔比较轻松恢复原始值:

True = 1==1
False = 1==0

或者通过将整数文字转换为bools:

True = bool(1)  # actually every number except 0 works
False = bool(0)