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

pax*_*blo 32 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
Run Code Online (Sandbox Code Playgroud)

谁能解释这种奇怪的行为?我认为这与Python的对象模型有关,但我不确定.

它是Cygwin下的2.5.2版本.

bal*_*pha 76

Python有这两个(以及其他)内置对象.它们只是物体; 在开始的时候,他们没有任何的名称还没有,但要知道我们所说的,让我们给他们打电话0x600D0xBAD.

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

因为0x600D0xBAD知道,他们通常使用的名称TrueFalse,那就是当他们得到打印他们的输出,即__str__方法0x600D回报'True'等.

True = False
Run Code Online (Sandbox Code Playgroud)

现在将名称绑定True到另一个对象.从现在起,这两个名字TrueFalse指代相同的对象0xBAD,其中,打印输出时False.

True = True
Run Code Online (Sandbox Code Playgroud)

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

True = not True
Run Code Online (Sandbox Code Playgroud)

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

既然这个名字True现在再一次引用了对象0x600D,则调用print True输出True,并且世界再次变好.


Jam*_*mes 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
Run Code Online (Sandbox Code Playgroud)

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


Ign*_*ams 18

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


gho*_*g74 12

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

>>> import keyword
>>> keyword.iskeyword('True')
False
Run Code Online (Sandbox Code Playgroud)

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

  • 注意:这是在python 3中修复的,True是[keyword](https://docs.python.org/3/reference/lexical_analysis.html#keywords). (2认同)