Reputation: 127
When an IF statement is called on an instance of a list object, is there a magic method that is used to evaluate whether True or False is returned? For example,
a = []
b = [1, 2, 3]
if a == b: # <---- __eq__() is called and returns False
pass
if a: # <---- what is called here that returns False?
pass
Is it: a.__bool__ (a.__nonzero__)? a.__len__?
or something else completely?
Upvotes: 0
Views: 205
Reputation: 198418
Experiment time!
class Falsy:
def __nonzero__(self):
print("it's __nonzero__")
return False
def __len__(self):
print("it's __len__")
return 0
def __bool__(self):
print("it's __bool__")
return False
def __eq__(self, other):
print("it's __eq__")
return False
if Falsy():
pass
# => it's __bool__
You can experiment with removing the methods to confirm which priority they are tested in (__bool__
, then __len__
, for Python 3).
Upvotes: 2
Reputation: 23119
@ymonad gives the best answer in the question's comments, by simply referring to this doc:
https://docs.python.org/3/library/stdtypes.html#truth-value-testing
I don't want credit for this. I just can't handle it when the best answer isn't even an answer. If one can simply point to documentation, that will just about always be the best answer.
...grrrr...hey @ymonad, can I pass you a bounty or something, lol?
Upvotes: 2
Reputation: 8695
Consulting the C-Python API documentation for PyList ...
https://docs.python.org/3.7/c-api/list.html
... we can see there is no list-specific “as bool” function. The only thing which can return the “truth” value is PyList_Size(PyObject *list)
, so the answer must be a.__len__()
is used.
Disclaimer: At least, for CPython.
Upvotes: 0
Reputation: 31354
From the documentation https://docs.python.org/2/reference/datamodel.html#object.nonzero:
object.__nonzero__(self)
Called to implement truth value testing and the built-in operation bool()
; should return False
or True
, or their integer equivalents 0
or 1
. When this method is not defined, __len__()
is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__()
nor __nonzero__()
, all its instances are considered true.
And for Python 3 https://docs.python.org/3.7/reference/datamodel.html#object.nonzero:
object.__bool__(self)
Called to implement truth value testing and the built-in operation bool()
; should return False
or True
. When this method is not defined, __len__()
is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__()
nor __bool__()
, all its instances are considered true.
Try:
class MyList(list):
def __bool__(self):
return True
print(bool(list([])))
if list([]):
print('This does not print')
print(bool(MyList([])))
if MyList([]):
print('This prints')
Upvotes: 0
Reputation: 3522
You may want to refer to this answer.
I am not sure what you mean. If I assume you are looking for a Java's .equals() equivalent, I am going to say, there is no such thing in python.
An empty list is always False in python.
Upvotes: -1