Suppose I have a list Q. In the following code:
while Q:
do_something()
Q.pop()
in the while Q statement, what method of the list Q is invoked? Is it the __len__ method?
Suppose I have a list Q. In the following code:
while Q:
do_something()
Q.pop()
in the while Q statement, what method of the list Q is invoked? Is it the __len__ method?
In Python 3.x, it's __bool__ or __len__:
object.__bool__(self)Called to implement truth value testing and the built-in operation
bool(); should returnFalseorTrue. 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.
In 2.x it was named __nonzero__; see what's new in 3.0.
From python's documentation:
Any object can be tested for truth value, for use in an
iforwhilecondition or as operand of the Boolean operations below. The following values are considered false:
- (...)
- any empty sequence, for example,
'',(),[].- (...)
- instances of user-defined classes, if the class defines a
__bool__()or__len__()method, when that method returns the integer zero orboolvalueFalse. [Additional information on these special methods may be found in the Python Reference Manual (Basic customization).]All other values are considered true — so objects of many types are always true.
Operations and built-in functions that have a Boolean result always return
0orFalsefor false and1orTruefor true, unless otherwise stated. (Important exception: the Boolean operationsorandandalways return one of their operands.)
Yes, __len__ does get called in this case.
Let's see this code snippet:
class clist(list):
def __len__(self):
print "Called"
Q = clist([1,2,3,4])
while Q:
break
Output:
Called
Traceback (most recent call last):
File "a.py", line 10, in <module>
while Q:
TypeError: an integer is required
But, if I remove the method,
class clist(list):
pass
Q = clist([1,2,3,4])
while Q:
break
the code will run just fine, but won't print anything.
So yes, __len__ does get called.