How can I define __getattr__ to operate on all items of container and pass arguments?

Jeremy jlconlin at gmail.com
Tue Feb 15 22:58:11 CET 2011


On Tuesday, February 15, 2011 1:44:55 PM UTC-7, Chris Rebert wrote:
> On Tue, Feb 15, 2011 at 12:29 PM, Jeremy <jlco... at gmail.com> wrote:
> > I have a container object.  It is quite frequent that I want to call a function on each item in the container.  I would like to do this whenever I call a function on the container that doesn't exist, i.e., the container would return an attribute error.
> 
> s/function/method/
> 
> > For example
> >
> > class Cont(object):
> >    def __init__(self):
> >        self.items = []
> >
> >    def contMethod(self, args):
> >        print("I'm in contMethod.")
> >
> >    def __getattr__(self, name):
> >        for I in self.items:
> >            # How can I pass arguments to I.__dict__[name]?
> >            I.__dict__[name]
> >
> <snip>
> > The trouble I'm getting into is that I can't pass arguments to the attributes in the contained item.  In the example above, I can't pass 'abc' to the 'itemMethod' method of each item in the container.
> >
> > Does someone know how I can accomplish this?
> 
> Recall that:
> x.y(z)
> is basically equivalent to:
> _a = x.y
> _a(z)
> 
> So the arguments haven't yet been passed when __getattr__() is
> invoked. Instead, you must return a function from __getattr__(); this
> function will then get called with the arguments. Thus (untested):
> 
> def __getattr__(self, name):
>     def _multiplexed(*args, **kwargs):
>         return [getattr(item, name)(*args, **kwargs) for item in self.items]
>     return _multiplexed

Perfect, that's what I needed.  I realized that I didn't have the arguments to the function, but couldn't figure out how to do it.  This works like a charm.  Thanks a lot!

Jeremy



More information about the Python-list mailing list