<p>传递方法名,而不是方法。使用<a href="https://docs.python.org/2/library/functions.html#getattr" rel="nofollow">^{<cd1>}</a>获取方法:</p>
<pre><code>class Parent(object):
def a(self, text):
raise NotImplementedError("called Parent.a")
def b(self, text):
raise NotImplementedError("called Parent.b")
class ChildA(Parent):
def a(self, text):
return "A.a: {}".format(text)
def b(self, text):
return "A.b: {}".format(text)
class ChildB(Parent):
def a(self, text):
return "B.a: {}".format(text)
def b(self, text):
return "B.b: {}".format(text)
children = [ ChildA(), ]
childrenMixed = children + [ ChildB(), ]
def exec_all(methodname, children):
for child in children:
method = getattr(child, methodname)
print(method("Hello world"))
print
exec_all('a', children)
exec_all('b', children)
exec_all('a', childrenMixed)
exec_all('b', childrenMixed)
exec_all('a', childrenMixed)
exec_all('b', childrenMixed)
</code></pre>
<p>收益率</p>
<pre><code>A.a: Hello world
A.b: Hello world
A.a: Hello world
B.a: Hello world
A.b: Hello world
B.b: Hello world
A.a: Hello world
B.a: Hello world
A.b: Hello world
B.b: Hello world
</code></pre>
<hr/>
<p>在Python2中,<code>ChildA.a</code>是一种未绑定的方法。与Python3不同,unbound方法检查第一个参数是否是本例中正确类的实例<code>ChildA</code>。这就是为什么打电话来</p>
<pre><code>ChildA.a(ChildB(), text)
</code></pre>
<p>引发<code>TypeError</code>:</p>
<pre><code>TypeError: unbound method a() must be called with ChildA instance as first argument (got ChildB instance instead)
</code></pre>
<p>在Python3中,这样的调用是可以的,不过如果您这样做的话,最好是让所有这些方法都成为普通函数,而不是方法。你知道吗</p>
<hr/>
<p>听起来您确实希望在发布函数调用时保留其形式:</p>
<pre><code>exec_all(ChildA.a, children)
exec_all(ChildA.b, children)
exec_all(ChildA.a, childrenMixed)
exec_all(ChildA.b, childrenMixed)
exec_all(Parent.a, childrenMixed)
exec_all(Parent.b, childrenMixed)
</code></pre>
<p>如果我们将此作为一个固定的需求,那么您可以通过定义<code>exec_all</code>获得所需的行为,如下所示:</p>
<pre><code>class Parent(object):
def a(self, text):
raise NotImplementedError("called Parent.a")
def b(self, text):
raise NotImplementedError("called Parent.b")
class ChildA(Parent):
def a(self, text):
return "A.a: {}".format(text)
def b(self, text):
return "A.b: {}".format(text)
class ChildB(Parent):
def a(self, text):
return "B.a: {}".format(text)
def b(self, text):
return "B.b: {}".format(text)
children = [
ChildA(),
]
childrenMixed = children + [
ChildB(),
]
def exec_all(method, children):
methodname = method.__name__
for child in children:
method = getattr(child, methodname)
print(method("Hello world"))
exec_all(ChildA.a, children)
exec_all(ChildA.b, children)
exec_all(ChildA.a, childrenMixed)
exec_all(ChildA.b, childrenMixed)
exec_all(Parent.a, childrenMixed)
exec_all(Parent.b, childrenMixed)
</code></pre>
<p>但是故意传递错误的方法并不是一个好的设计。如果希望调用<code>ChildB.a</code>,则不应传递<code>ChildA.a</code>。Python并没有使这变得简单,因为这不是OOP的工作方式。
传递<strong>正确的</strong>方法或将方法名作为字符串传递(如上所示)都是更好的选择。你知道吗</p>