我正在写一个元类,我想在__new__和__init__之间调用一个额外的方法。
如果我在__new__之前或__init__之后调用该方法,我可以写一下。
class Meta(type):
def __call__(cls):
ret = type.__call__()
ret.extraMethod()
我的诱惑是写
class Meta(type):
def __call__(cls):
ret = cls.__new__(cls)
ret.extraMethod()
ret.__init__()
return ret
只是重现了.__ call__类型的功能。但我担心可能会有一些微妙的类型.__ call__我已经省略了,这将导致我的元类实现时的意外行为。
我无法从__init__或__new__调用extraMethod,因为我希望我的元类用户能够像普通的Python类一样覆盖__init__和__new__,但仍然可以在extraMethod中执行重要的设置代码。
谢谢!
答案 0 :(得分:1)
如果您真的希望完全按照您的说法做,我可以建议您使用以下解决方案:
def call_after(callback, is_method=False):
def _decorator(func):
def _func(*args, **kwargs):
result = func(*args, **kwargs)
callback_args = (result, ) if is_method else ()
callback(*callback_args)
return result
return _func
return _decorator
class Meta(type):
def __new__(mcs, class_name, mro, attributes):
new_class = super().__new__(mcs, class_name, mro, attributes)
new_class.__new__ = call_after(
new_class.custom_method,
is_method=True
)(new_class.__new__)
return new_class
class Example(object, metaclass=Meta):
def __new__(cls, *args, **kwargs):
print('new')
return super().__new__(cls, *args, **kwargs)
def __init__(self):
print('init')
def custom_method(self):
print('custom_method')
if __name__ == '__main__':
Example()
此代码将生成以下结果:
new
custom_method
init