34

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

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 版本。

4

5 回答 5

78

Python 有这两个(以及其他)内置对象。它们只是对象;一开始,它们还没有任何名字,但要知道我们指的是什么,我们称它们为0x600Dand 0xBAD

在开始执行 Python (2.x) 脚本之前,名称True被绑定到 object 0x600D,并且 nameFalse被绑定到 object 0xBAD,所以当程序引用 时True,它会查看0x600D.

因为0x600Dand0xBAD知道它们通常用于名称Trueand False,这就是它们在打印时输出的内容,即返回的__str__方法等。0x600D'True'

True = False

现在将名称绑定True到不同的对象。从现在开始,两个名称TrueFalse引用同一个对象0xBAD,当打印时,输出False

True = True

并没有真正做任何事情:它获取由 name 引用的对象True,并将新(和旧)名称绑定True到该对象。由于(因为上一步)True是指0xBAD在此之前,它仍然是指0xBAD在此之后。因此,打印仍然输出False

True = not True

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

由于名称True现在再次指代对象0x600D,调用print True输出True,世界再次美好。

于 2010-01-13T07:38:40.790 回答
45

想象一下:

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

完全相同的事情正在发生,但在您的版本中它令人困惑,因为您不希望您可以重新定义 True 和 False。

于 2010-01-13T07:21:37.747 回答
18

在 2.x 中,True 和 False 不是关键字,因此可以以这种方式隐藏内置函数。

于 2010-01-13T07:14:20.907 回答
12

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

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

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

于 2010-01-13T07:25:44.487 回答
0

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

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

或者通过将整数文字转换为布尔值:

True = bool(1)  # actually every number except 0 works
False = bool(0)
于 2016-04-21T07:18:40.883 回答