标题不是很清楚,但我会尝试解释。
有这个课程:
class Wrapped(object):
def method_a(self):
# do some operations
return n
def method_b(self):
# also do some operations
return n
我希望有一个类与此相同的类:
class Wrapper(object):
def __init__(self):
self.ws = [Wrapped(1),Wrapped(2),Wrapped(3)]
def method_a(self):
results=[Wrapped.method_a(w) for w in self.ws]
sum_ = sum(results,0.0)
average = sum_/len(self.ws)
return average
def method_b(self):
results=[Wrapped.method_b(w) for w in self.ws]
sum_ = sum(results,0.0)
average = sum_/len(self.ws)
return average
显然这不是手边的实际问题(它不仅仅是两种方法),而且这段代码也是不完整的(只包含解释问题的最小值)。
所以,我正在寻找的是一种获得这种行为的方法。意思是,在包装器类中调用哪个方法,为所有Wrapped类对象调用该方法并返回其结果的平均值。
可以吗?怎么样?
提前致谢。
修改
谢谢你的答案...看到他们的解决方案后,这一切似乎都很明显:)我选择了Alex Martelli的答案,因为它很好地解释了解决方案。另一个答案也很有用,这也是我投票的原因。
答案 0 :(得分:3)
虽然非常可行,但它有点棘手,因为获取方法(或其他属性)及其调用是单独的操作。这是一个解决方案:
class Wrapper(object):
def __init__(self):
self.ws = [Wrapped(1),Wrapped(2),Wrapped(3)]
def __getattr__(self, n):
meth = getattr(Wrapped, n)
def caller():
results = [meth(w) for w in self.ws]
sum_ = sum(results,0.0)
average = sum_/len(self.ws)
return average
return caller
它有点过分简单(假设在获取和调用之间self.ws
没有变化 - 当然可以在获取时获得“快照”self.ws
,如果这是所需的语义;不使用@functools.wraps
所以如果那些需要保留,则不保留docstring& c,但应该主要用于您的目的。
答案 1 :(得分:1)
您可以使用getattr来对此进行调用(在对象上调用'任意'方法):
以此为例:
# this fetches you references to the 'method_a' methods for objects in self.ws
funcs = [getattr(wrapped_obj, "method_a") for wrapped_obj in self.ws]
# now execute them to get the results
results = [func() for func in funcs]
您的其余代码将保持不变。
答案 2 :(得分:1)
您可以通过在Wrapper
中实现__getattr__
方法来执行此操作,该方法返回一个函数,该函数将调用转发给所有包装的对象。这是一个简单返回结果的基本实现示例:
import functools
class Wrapper(object):
def __init__(self, *args):
self._targets = args
def _broadcast(self, name, *args, **kwargs):
return [getattr(t, name)(*args, **kwargs) for t in self._targets]
def __getattr__(self, name):
return functools.partial(self._broadcast, name)
请注意,只有在找不到属性时才会调用__getattr__
,因此您在Wrapper
中定义的所有方法名称都不会被转发(例如上面示例中的_broadcast
)。
答案 3 :(得分:0)
您可以使用特殊的getattr方法执行此操作。