So I've been messing around with the standard operators in classes to try and see what i can make, but i haven't been able to find how to edit the boolean and
operator.
I can edit the bitwise &
operator by defining __and__(self)
, but not the way that and
behaves. Does anyone know how I can change the behavior of a and b
where a
and b
are instances of the class I'm making?
Thanks in advance!
In Python 2, and
and or
access __nonzero__
:
>>> class Test(object):
... def __nonzero__(self):
... print '__nonzero__ called'
... return True
...
>>> Test() and 1
__nonzero__ called
1
In Python 3, __nonzero__
has been renamed to __bool__
.
>>> class Test:
... def __bool__(self):
... print('__bool__ called')
... return True
...
>>> Test() and 1
__bool__ called
1
Note that short-circuit evaluation might suppress a call to __nonzero__
or __bool__
.
>>> 0 and Test()
0
>>> 1 or Test()
1
Another speciality to be aware of is that Python is trying to access __len__
if __nonzero__
/ __bool__
is not defined and treats the object as truthy if __len__
returns a value other than 0
. If both methods are defined, __nonzero__
/ __bool__
wins.
>>> class Test:
... def __len__(self):
... return 23
...
>>> Test() and True
True
>>>
>>> class Test:
... def __len__(self):
... return 23
... def __bool__(self):
... return False
...
>>> Test() and True
<__main__.Test object at 0x7fc18b5e26d8> # evaluation stops at Test() because the object is falsy
>>> bool(Test())
False
Is there any way i can have this return something other than a bool, like, say, a list of bools?
Unfortunately, no. The documentation states that the method should return False
or True
but in fact you get a TypeError
if you let it return something else.
>>> class Test:
... def __bool__(self):
... return 1
...
>>> Test() and 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __bool__ should return bool, returned int
>>>
>>> bool(Test())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __bool__ should return bool, returned int
The and
operator converts the first operands to boolean using __bool__
, and then does a predefined action to the booleans (if first.__bool__()
is True
, return second, else return first). There is no way to change this behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With