On Wed, 11 May 2011 19:05:03 +0000, Chris Torek wrote: > In article <4dcab8bf$0$29980$c3e8da3$54964...@news.astraweb.com> Steven > D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: >>When you call len(x) you don't care about the details of how to >>calculate the length of x. The object itself knows so that you don't >>have to. The same applies to truth testing. >> >>I have a data type that is an array of lists. When you call "if len(x) > >>0" on it, it will blow up in your face, because len(x) returns a list of >>lengths like [12, 0, 2, 5]. But if you say "if x", it will do the right >>thing. You don't need to care how to truth-test my data type, because it >>does it for you. By ignoring my type's interface, and insisting on doing >>the truth-test by hand, you shoot yourself in the foot. > > What this really points out is that "if x" and "if len(x) > 0" are > *different tests*.
*Potentially* different tests. Which is exactly the point. Given an arbitrary object, the developer doesn't know what test is appropriate. Should I write len(x) == 0 or list(x) == [] or x.next is None or something else? How can I tell which is appropriate without knowing everything about the internals of every object I ever see? But if x is a non-broken object, then you don't have to. Just test on x itself, because it knows what to do to be considered a truth value. Of course there may be objects where this doesn't work. There are no guarantees in Python. You can't even guarantee that printing an object won't blow up: >>> class Broken: ... def __str__(self): ... return "... %s ..." % 1/2 ... __repr__ = __str__ ... >>> b = Broken() >>> b Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __str__ TypeError: unsupported operand type(s) for /: 'str' and 'int' > Consider xml.etree.ElementTree "Element" objects. > The documentation says, in part: > > In ElementTree 1.2 and earlier, the sequence behavior means that an > element without any subelements tests as false (since it's an empty > sequence), even if it contains text and attributions. ... > > Note: This behavior is likely to change somewhat in ElementTree 1.3. > To write code that is compatible in both directions, use ... > "len(element)" to test for non-empty elements. > > In this case, when x is an Element, the result of bool(x) *could* mean > just "x has sub-elements", but it could also/instead mean "x has > sub-elements, text, or attributions". Either behaviour is correct, but a semantic change to the class means that you have to do more work if you care about supporting both versions in the same code base. That is a neat example of where you might choose *not* to let an object decide for itself whether it is true or false, but instead impose your own definition on it. -- Steven -- http://mail.python.org/mailman/listinfo/python-list