如何确保为层次结构中的每个类调用方法(一次,如果存在)?



我有一个类层次结构,其中子类可以选择定义一个具有给定名称的方法,例如do_it,并希望在基类中编写一个函数,例如do_all,以确保每个这样的方法将按类层次结构的顺序执行。我能最接近实现这一点的是:

class A(object):
def do_it(self):
print 'Do A'
def do_all(self):
# Better, from comments and answers: vars(type(self))
for c in reversed(self.__class__.__mro__[:-1]):
c.do_it(self)
class B(A):
def do_it(self):
print 'Do B'
class C(B):
def no_do_it(self):
pass
class D(C):
def do_it(self):
print 'Do D'

这几乎可以按预期工作,例如B().do_all()给出

Do A
Do B

但它会导致对Bdo_it的所有类的重复调用。例如D().do_all()给出

Do A
Do B
Do B
Do D

如何避免未实现它的类对父do_it的重复调用?这甚至是实现我想要做的事情的正确方法吗?

您可以检查是否已看到该函数:

def do_all(self):
seen = set()
for c in reversed(self.__class__.__mro__[:-1]):
if c.do_it not in seen:
seen.add(c.do_it)
c.do_it(self)

请注意,在 Python 2 中,您需要从未绑定方法中提取函数,如c.do_it.__func__(或使用six.get_unbound_function)。

另一种方法是检查__dict__

def do_all(self):
for c in reversed(self.__class__.__mro__[:-1]):
if 'do_it' in c.__dict__:
c.do_it(self)

相关内容

  • 没有找到相关文章

最新更新