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

Chris Rebert clp2 at rebertia.com
Tue Feb 15 15:44:55 EST 2011


On Tue, Feb 15, 2011 at 12:29 PM, Jeremy <jlconlin 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

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list