作为回答另一个问题的一部分,我写了下面的代码,其行为乍一看似乎很奇怪:
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版本。
答案 0 :(得分:75)
Python有这两个(以及其他)内置对象。它们只是物体;在开始时,它们还没有任何名称,但要知道我们所指的是什么,我们称之为0x600D
和0xBAD
。
在开始执行Python(2.x)脚本之前,名称True
绑定到对象0x600D
,名称False
绑定到对象{{1因此,当程序引用0xBAD
时,它会查看True
。
由于0x600D
和0x600D
知道它们通常由名称0xBAD
和True
使用,因此它们在打印时会输出,即{{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)