All of this just boils down to Python providing an implicit bool cast in syntactic situations that expect conditional expressions, including if [1]. So "if x:" is equivalent to "if bool(x)". Perhaps that is the part that is not immediately obvious, being implicit to Python conditional syntax.<div>
<div><br></div><div>Python also provides a mechanism for customization of a wide variety of behavior that is not obvious without reading the [excellent] documentation [2]. So the following three forms will implicitly call the special method names:</div>
</div><div><br></div><div> if x: => if bool(x): => if x.__bool__(): [3]</div><div><br></div><div> if x == []: => if x.__eq__([]):</div><div><br></div><div> if len(x) == 0: => if x.__len__() == 0:</div>
<div><br></div><div>Other than the implicit cast to bool for conditional syntax and the implicit calls to special method names as appropriate I am not clear that there is any remaining mystery for this question. And the language reference makes all of the above very clear, so I highly recommend it. </div>
<div><br></div><div>The only caveat is that builtin types don't always act the same way as user defined types (classes). Not sure if the few differences are well documented, but to be honest that hasn't bit me hard enough that I needed to look it up. I do know that the builtin list has a __eq__ method and a __len__ method, but not a __bool__ method (which it doesn't need [3]).</div>
<div><br></div><div>-eric</div><div><br></div><div>[1] <a href="http://docs.python.org/dev/py3k/reference/compound_stmts.html#the-if-statement">http://docs.python.org/dev/py3k/reference/compound_stmts.html#the-if-statement</a></div>
<div>[2] <a href="http://docs.python.org/dev/py3k/reference/datamodel.html#special-method-names">http://docs.python.org/dev/py3k/reference/datamodel.html#special-method-names</a></div><div>[3] <a href="http://docs.python.org/dev/py3k/reference/datamodel.html#object.__bool__">http://docs.python.org/dev/py3k/reference/datamodel.html#object.__bool__</a></div>
<div> so if __bool__ doesn't exist it tries __len__ and so forth.</div>