I was checking some of CPython's tests and in this file I saw a test case which was strange to me:
def test_math(self):
...
self.assertIsNot( False, False)
At first I thought it is a typo and it should be self.assertIs( False, False)
but when I tried it on the Python console the result was False
:
>>> False is False
<stdin>:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False
>>>
>>> id(False)
140078839501184
>>> id( False)
140078839621760
Why does
make it a different object?
Comments suggest that False
is 0
. So maybe the better question should be why is this?
CodePudding user response:
Because a bool
is a type of int
:
>>> isinstance(False, int)
True
>>> False == 0
True
a bool is accepted by functions that take ints as inputs (including all the standard operators), and those functions will generally return ints:
>>> True False
1
>>> True * 2
2
>>> True ** False
1
or sometimes floats:
>>> True / True
1.0
Specifically, putting
in front of a number is a "unary plus", the opposite of a "unary minus" which returns the negative of its operand:
>>> True
1
>>> -True
-1
>>> False
0
>>> -False
0
Although this bool/int behavior catches most people off guard the first time they find it, it allows for some useful shortcuts; for example, you can sum
a bunch of bools to find the number of True
values:
>>> sum([True, True, False, False, True])
3
>>> sum(s.startswith("a") for s in ("apple", "banana", "pear", "avocado"))
2
CodePudding user response:
When you apply arithmetic operations to boolean values they are turned into int
.
In [10]: type( False)
Out[10]: int
In [11]: type(False)
Out[11]: bool
CodePudding user response:
False
is equal to 0
and 0
is a literal.
since you are not allowed to use is
with literals(because they are not stored in memory), you get the warning.