Strange behavior when determining True in Python

This is not a practical problem. I am just curious to find out about some strange behavior that I have been observing, and I am wondering if I understand the "yes" operator correctly.

Here's the predictable output of the Python interpreter:

>>> True is True True >>> (1==1) is True True 

Now let's define the True variable:

 >>> True = 'abc' >>> True == 'abc' True >>> True is 'abc' True 

The interpreter will still return “True” for Boolean operations, but the results of logical operations are considered equivalent to neither “abc” nor True.

 >>> (1==1) True >>> (1==1) is 'abc' False >>> (1==1) is True False 

Can anyone explain this weird behavior?

+8
python boolean boolean-expression
source share
3 answers

To add a little more to your own answer (there should be a comment, but formatting is required for a long time):

 python2.7 ... >>> import __builtin__ >>> id(True) 7744528 >>> id(__builtin__.True) 7744528 >>> True = 'abc' >>> id(True) 34386540544 

The value from id is the (essentially) internal identifier or "true name" of the object in Python, if you will. (This literally turns the C pointer into an integer.) The is test compares the identifier of an object.

 >>> 1==1 True >>> id(1==1) 7744528 

This shows that the logical result of the comparison is the “old” True , which is still available as __builtin__.True .

You have re-linked the name __main__.True (your current module at the prompt of the interpreter >>> __main__ ):

 >>> True 'abc' >>> __builtin__.True True 

and

 >>> import __main__ >>> id(__main__.True) 34386540544 >>> __main__.True 'abc' >>> 

The same thing happens in Python beginner programs when they write functions such as:

 def foo(list): ... 

list is a built-in function, but inside the foo function, the name is bound with an argument. Then somewhere in the piece ... they get a surprise:

  x = list(y) 

They expect this to call __builtin__.list , but instead try to call their local variable as a function.

(It is possible, but not generally a good style, to import __builtin__ and instead name things through these names. It is also possible to strip the names __builtin__ , but this is even worse. :-))

+2
source share

As often happens here, I think I understood the answer when I typed the question.

There are two “True” ones: one is a boolean and the other is a True variable; initially they are equal to each other. This is why logical operations like (1 == 1) can return True even when a variable named True has been changed - they return the logical value True. However, they are not equal to the new value of the variable "True", which is a string.

+6
source share

This happens when the namespace and interactive console hide it.

Initially, you have normal True , which is part of the __builtin__ module.

When you override True , you actually define it in the current module, which in this case defaults to __main__ .

So you actually have two different objects. __builtin__.True and __main__.True .

 In [1]: import __builtin__, __main__ In [2]: True = "a bad idea" In [3]: __main__.True Out[3]: 'a bad idea' In [4]: __builtin__.True Out[4]: True 
+5
source share

All Articles