class with __len__ member fools boolean usage "if x:" ; bad coding style?
Peter Otten
__peter__ at web.de
Tue Jun 29 14:34:21 EDT 2004
Heiko Wundram wrote:
> Am Dienstag, 29. Juni 2004 07:59 schrieb Peter Otten:
>> Now you have an object that neither behaves consistently as a boolean nor
>> as a sequence, I fear you in for even subtler bugs...
>
> That isn't necessarily true... Given the following example, I'd say what
> __nonzero__ and __len__ implement is quite understandable, and if
> documented, the programmer isn't in for any bug:
>
> <code>
>
> import time
>
> class ID(object):
>
> def __init__(self):
> self.__id = "test"
>
> def __len__(self):
> return len(self.__id)
>
> class Host(ID):
>
> def __init__(self):
> self.__timeout = time.time() + 30
>
> def __nonzero__(self):
> return self.__timeout >= time.time()
>
> </code>
>
> nonzero and len implement something completely different, where __len__ is
> an operator on the underlying ID of a Host, and __nonzero__ is an operator
> on the Host itself, to check whether the Host has timed out.
In Python, you don't normally check for a timeout (google for LBYL), you'd
rather throw an exception. This avoids problems like
h = Host()
if h:
sleep(justLongEnoughForHostToTimeOut)
h.someOperation() # fails due to timeout
> It doesn't make sense to have __nonzero__ refer to the ID (which is always
> nonzero, a string), and it neither makes sense to have __len__ refer to
> the Host (which doesn't have a length), so the situation here is pretty
> clear (IMHO).
A __len__() without a __getitem__() method doesn't make sense to me. But
maybe your example is just too terse...
> But, as always, documentation is better than guessing. ;)
No amount of documentation can heal an unintuitive API.
The convention of using bool(o) as an abbreviation of o.isValid() for
non-sequences and of len(o) != 0 for sequences seems natural to me. Mixing
these two meanings or even adding "was this parameter provided" as a third
one will result in highly ambiguous code that is bound to break.
Peter
More information about the Python-list
mailing list