<p>一种方法是覆盖<code>Bar</code>的<code>__getattr__</code>:</p>
<pre class="lang-py prettyprint-override"><code>class Bar:
def __init__(self, fooInstances):
self.fooInstances = fooInstances
def __getattr__(self, attr):
try:
getattr(self.fooInstances[0], attr)
except AttributeError:
raise AttributeError(f"'Bar' object has no attribute '{attr}'")
else:
def foo_wrapper(*args, **kwargs):
for foo_inst in self.fooInstances:
getattr(foo_inst, attr)(*args, **kwargs)
return foo_wrapper
</code></pre>
<p>如果对<code>Bar</code>对象的属性查找失败,则调用<code>__getattr__</code>上的<code>Bar</code>。然后,我们尝试查看<code>Foo</code>实例是否具有该属性;如果不是,则引发<code>AttributeError</code>,因为<code>Bar</code>和<code>Foo</code>都不接受该属性。但是,如果<code>Foo</code>确实有它,我们将返回一个函数,当调用该函数时,在<code>Bar</code>对象中的<code>Foo</code>的每个瞬间调用方法(<code>attr</code>)</p>
<p>用法:</p>
<pre><code> ...
# changed this method in Foo to see the passing-an-argument case
def addOneToA(self, val):
self.a += 1
print(f"val = {val}")
...
>>> bar = Bar([Foo(), Foo(), Foo()])
>>> bar.addOneToB()
>>> [foo.b for foo in bar.fooInstances]
[1, 1, 1]
>>> bar.addOneToA(val=87) # could also pass this positionally
val = 87
val = 87
val = 87
>>> bar.this_and_that
AttributeError: 'Bar' object has no attribute 'this_and_that'
</code></pre>