pre-PEP generic objects

Ian Bicking ianb at colorstudy.com
Fri Dec 3 11:59:57 EST 2004


Istvan Albert wrote:
> Steven Bethard wrote:
> 
>  > The question is not how easy it is to write,
>  > but how many times it's going to get written.
> 
> but with that logic we could  create a standard
> "looping" construct called loop(x) that would stand in for
> 
> for i in range(x):

IMHO, that example is quite the opposite of what you are advocating. 
range() is a simple function, and one which could be written by anyone 
with little chance of flaw.  Why not do:

i = 0
while i < x
     ...
     i += 1

?  The three arguments to range are all present (how valuable are a few 
defaults).  It's more general.  You can extend it and modify it easily. 
  These are all the same properties of bunch.  Easy things have value; 
maybe that applies here, but saying that it is easy is not the same as 
saying it isn't valuable.  For instance, we now have the sorted 
function, equivalent to:

def sorted(lst, *args, **kw):
     lst = list(list)
     lst.sort(*args, **kw)
     return lst

People have been writing this function over and over.  Only there are a 
few subtlely different ways you can implement it, and you'll never know 
which from the function name alone.  dict's keyword argument constructor 
is similar.  And maybe bunch is similar; at least, I'd argue for or 
against it based on that, not merely on how easy it is to reimplement. 
"If the implementation is easy to explain, it may be a good idea." 
(import this)

If it existed, I'd probably use it some where I'm currently using 
dictionaries (but where I don't want to give the data behavior), and I'd 
probably subclass it.  Now, when it doesn't exist, I frequently 
implement the behavior in classes that have other logic as well, and I 
almost never use it without logic; I use dict() with its keyword 
argument constructor, and just suffer the quotation marks when I'm 
retrieving members.

BTW, in class that look like bunch, I usually implement it like:

class bunch(object):
     def __init__(self, **kw):
         for name, value in kw.items():
             # IMPORTANT!  This is subclass friendly: updating __dict__
             # is not!
             setattr(self, name, value)

     def __call__(self, **kw):
         # I'm not entirely happy with this:
         new_values = self.__dict__.copy()
         new_values.update(kw)
         return self.__class__(**new_values)

-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org



More information about the Python-list mailing list