class with __len__ member fools boolean usage "if x:" ; bad coding style?

george young gry at ll.mit.edu
Fri Jun 25 11:37:13 EDT 2004


[Python 2.3.3, x86 linux]
I had developed the habit of using the neat python form:
   if someinstance:
      someinstance.memb()

because it seems cleaner than "if someinstance is not None".
{please no flames about "is not None" vs. "!= None" ...}

This seemed like a good idea at the time :().  Twice, recently,
however, as my
app grew, I thought, hmm... it would make things clearer if I gave
this container class a __len__ member and maybe a __getitem__. Great,
code looks
nicer now... crash,crash, many expletives deleted...  

Its great to be able to say containerinstance[seq] instead of
containerinstance.steps[seq], but I've also changed the semantics of 
(containerinstance) in a boolean context.  My app breaks only in the
seldom
case that the container is empty.

Obviously I know how to fix the code, but I'm wondering if this isn't
a message
that "if containerinstance:" is not a good coding practice.  Or maybe
that one
should never *add* on sequence emulation to a class that's already in
use.
It may look like adding a __len__ and __getitem__ is just *extending*
the
functionality of the class, but in fact, it strongly *changes*
semantics of
existing usage of the class.  

I know the ref manual mentions this behaviour,
but I begin to wonder at the wisdom of a language design and common
usage pattern of (containerinstance) instead of
(len(containerinstance)) and (containerinstance is None) as a boolean
expression.
Comments?  Suggestions?



More information about the Python-list mailing list