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

Discussion in 'Python' started by Jeremy, Feb 15, 2011.

  1. Jeremy

    Jeremy Guest

    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.

    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]


    >>> C = Cont()
    >>> # Add some items to C
    >>>C.contMethod()

    I'm in contMethod.
    >>>C.itemMethod('abc')

    ??????????


    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?

    Thanks,
    Jeremy
    Jeremy, Feb 15, 2011
    #1
    1. Advertising

  2. Jeremy

    Chris Rebert Guest

    Re: How can I define __getattr__ to operate on all items of containerand pass arguments?

    On Tue, Feb 15, 2011 at 12:29 PM, Jeremy <> 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
    Chris Rebert, Feb 15, 2011
    #2
    1. Advertising

  3. Re: How can I define __getattr__ to operate on all items ofcontainer and pass arguments?

    On Tue, 15 Feb 2011 12:29:36 -0800, Jeremy wrote:

    > def __getattr__(self, name):
    > for I in self.items:
    > # How can I pass arguments to I.__dict__[name]?
    > I.__dict__[name]


    The same way you would pass arguments to any other function: with
    function call syntax.

    I.__dict__[name](arg1, arg2, arg3, ...)


    --
    Steven
    Steven D'Aprano, Feb 15, 2011
    #3
  4. Jeremy

    MRAB Guest

    Re: How can I define __getattr__ to operate on all items of containerand pass arguments?

    On 15/02/2011 20:29, Jeremy 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.
    >
    > 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]
    >
    >
    >>>> C = Cont()
    >>>> # Add some items to C
    >>>> C.contMethod()

    > I'm in contMethod.
    >>>> C.itemMethod('abc')

    > ??????????
    >
    >
    > 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?
    >

    Try calling it. All you're currently doing is looking it up and then
    discarding it.
    MRAB, Feb 15, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. benn
    Replies:
    2
    Views:
    593
  2. Timothy Madden

    How does #define operate ?

    Timothy Madden, Sep 27, 2004, in forum: C++
    Replies:
    5
    Views:
    623
    Xenos
    Sep 28, 2004
  3. key9
    Replies:
    3
    Views:
    313
  4. ashjas
    Replies:
    5
    Views:
    1,311
    James Kanze
    Feb 5, 2009
  5. Shriramana Sharma
    Replies:
    3
    Views:
    158
    Shriramana Sharma
    Jun 27, 2013
Loading...

Share This Page