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

J

Jeremy

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]

??????????


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
 
C

Chris Rebert

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]
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
 
S

Steven D'Aprano

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, ...)
 
M

MRAB

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]

??????????


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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top