【发布时间】:2020-08-17 12:00:24
【问题描述】:
我正在设计一个metaclass 来覆盖类__call__ 函数,在它之前递归地执行其超类__call__。思路是可以通过下面的代码得到如下结果:
Abstract
Base
Super
Child
class Abstract(metaclass=Meta):
def __call__(self):
print("Abstract")
class Base(Abstract):
def __call__(self):
print("Base")
class Super(Abstract):
def __call__(self):
print("Super")
class Parent:
def __call__(self):
print("Parent")
class Child(Base, Super, Parent):
def __call__(self):
print("Child")
到目前为止,我的Meta.new 如下:
def __new__(meta, name, bases, attr):
__call__ = attr['__call__']
def recursive_call(self):
for cls in [base for base in self.__class__.__bases__ if type(base) is Meta]:
cls.__call__(super(cls, self))
__call__(self)
attr['__call__'] = recursive_call
return super(Meta, meta).__new__(
meta, name, bases, attr
)
它实际上适用于单级继承类,但不适用于多级继承类。
如何修复此代码以实现我的目标? 或者是否有更简单的方法来实现它,而不是元类?
【问题讨论】:
-
这似乎是一种非常有问题的元类设计方式。
-
如果你真的希望
__call__表现得像这样,最好有一个单独的_call钩子并有一个带有__call__的基类,它调用所有_call方法,但是让__call__像这样工作本身就很奇怪。 -
这是什么:
cls.__call__(super(cls, self))应该做什么?? -
cls.__call__(super(cls, self))是我尝试将 超类对象 传递给它的__call__的方式,因为如果我传递了self,基类列表 重复一遍,我收到了RecursionError: maximum recursion depth exceeded while calling a Python object -
super(cls, self)不会返回超类对象。它将返回一个super对象。
标签: python python-3.x recursion metaclass