Reputation: 612814
My understanding is that &
is the bitwise AND operator. So I would expect it to have no meaning when applied to logicals. However, I see that:
>>> False & False
False
>>> False & True
False
>>> True & True
True
and so on. Likewise for the other bitwise operators.
So, why do these operators even accept logical operands? And where can I find the documentation that explains this? I searched for it but could not find an explanation.
Upvotes: 4
Views: 142
Reputation: 500207
So, why do these operators even accept logical operands?
bool
subclasses int
, and overrides __and__()
etc to return bool
for bool
operands.
For details, see PEP 285.
Specifically:
6) Should bool inherit from int? => Yes In an ideal world, bool might be better implemented as a separate integer type that knows how to perform mixed-mode arithmetic. However, inheriting bool from int eases the implementation enormously (in part since all C code that calls PyInt_Check() will continue to work -- this returns true for subclasses of int). Also, I believe this is right in terms of substitutability: code that requires an int can be fed a bool and it will behave the same as 0 or 1. Code that requires a bool may not work when it is given an int; for example, 3 & 4 is 0, but both 3 and 4 are true when considered as truth values.
and
class bool(int):
def __and__(self, other):
if isinstance(other, bool):
return bool(int(self) & int(other))
else:
return int.__and__(self, other)
__rand__ = __and__
def __or__(self, other):
if isinstance(other, bool):
return bool(int(self) | int(other))
else:
return int.__or__(self, other)
__ror__ = __or__
def __xor__(self, other):
if isinstance(other, bool):
return bool(int(self) ^ int(other))
else:
return int.__xor__(self, other)
__rxor__ = __xor__
Note how bool & bool
returns a bool
whereas bool & non-bool
inherit's int
's behaviour (i.e. returns an int
).
Here are some examples demonstrating these properties:
In [12]: isinstance(True, int)
Out[12]: True
In [13]: True & True
Out[13]: True
In [14]: True & 1
Out[14]: 1
The above behaviour does not apply to arithmetic operators. Those just use int
's behaviour:
In [15]: True + 0
Out[15]: 1
In [16]: True + False
Out[16]: 1
Upvotes: 8
Reputation: 26150
"Logicals", aka booleans, just represent a single bit either on or off, so of course bitwise operations work on them. What would make you expect bitwise operations not work on single bits?
You're inverting the inheritance of logical operations. The base case of bitwise operations is on single bit variables such as booleans. Bitwise operations on larger values are just an extended application of the single bit operation.
Upvotes: 0
Reputation: 1180
In Python 3.x True and False are keywords and will always be equal to 1 and 0.
Under normal circumstances in Python 2, and always in Python 3:
False object is of type bool which is a subclass of int:
object
|
int
|
bool
Upvotes: 0