As part of answering another question, I wrote the following code whose behaviour seems bizarre at first glance:
print True # outputs true
True = False; print True # outputs false
True = True; print True # outputs false
True = not True; print True # outputs true
Can anyone explain this strange behaviour? I think it has something to do with Python’s object model but I’m not sure.
It’s version 2.5.2 under Cygwin.
Python has these two (among others) builtin objects. They are just objects; in the beginning, they don’t have any names yet, but to know what we refer to, let’s call them
0x600Dand0xBAD.Before starting to execute a Python (2.x) script, the name
Truegets bound to the object0x600D, and the nameFalsegets bound to the object0xBAD, so when the program refers toTrue, it looks at0x600D.Because
0x600Dand0xBADknow that they are usually used by the namesTrueandFalse, that’s what they output when they get printed, i.e. the__str__method of0x600Dreturns'True'and so on.now binds the name
Trueto a different object. From now on, both namesTrueandFalserefer to the same object0xBAD, which, when printed, outputsFalse.doesn’t really do anything: It takes the object referred to by the name
True, and binds the new (and old) nameTrueto this object. Since (because of the previous step)Truerefers to0xBADbefore this, it still refers to0xBADafter this. Hence, printing still outputsFalse.first takes the object that the name
Trueis bound to, which is0xBAD. It gives this object to thenotoperator.notdoesn’t care (or know) what name is used here to refer to0xBAD, it just knows that when given0xBADit should return0x600D. This return value is then given to the assignment operator=, binding the nameTrueto this object.Since the name
Truenow once more refers to the object0x600D, callingprint TrueoutputsTrue, and the world is good again.