So why do these operators accept logical operands?
bool subclasses int and overrides __and__() , etc., to return bool operands for bool .
See PEP 285 for details.
In particular:
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 that bool & bool returns bool , while bool & non-bool inherits int behavior (i.e. returns int ).
Here are a few examples that demonstrate 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 behavior does not apply to arithmetic operators. They just use int behavior:
In [15]: True + 0 Out[15]: 1 In [16]: True + False Out[16]: 1
source share