题
作为回答另一个问题的一部分,我写了下面的代码,其行为好像奇异乍一看:
print True # outputs true
True = False; print True # outputs false
True = True; print True # outputs false
True = not True; print True # outputs true
谁能解释这种奇怪的行为?我认为这是与Python的对象模型,但我不知道。
这是2.5.2版的Cygwin下。
解决方案
Python有这两种(等等)内置对象。他们只是对象;在开始的时候,他们没有任何的名称还没有,但要知道我们所说的,我们姑且称之为0x600D
和0xBAD
。
在开始执行一个Python(2.x的)脚本之前,名称True
被绑定到对象0x600D
,并且名称False
被绑定到对象0xBAD
,所以当程序是指True
,它看起来在0x600D
。
由于0x600D
和0xBAD
知道它们通常使用的名称True
和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
,主叫print True
输出True
,世界是好的试。
其他提示
设想这样来代替:
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.X,真假不是关键字,因此有可能遮蔽内置插件这种方式。
您可以检查是否真/假是一个关键字:
>>> import keyword
>>> keyword.iskeyword('True')
False
由于它不是(在我的版本),分配真=假只是意味着“真”是另一种“可变的”名称。
您可以通过使用简单的布尔比较容易恢复到原来的值:
True = 1==1
False = 1==0
或者通过转换整数常量到布尔变量:
True = bool(1) # actually every number except 0 works
False = bool(0)