默认类型__call__是否比调用__new__和__init__还要多? [英] Does the default type.__call__ do more than call __new__ and __init__?
问题描述
我正在编写一个元类,并且我想在__new__和__init__之间调用一个附加方法.
I'm writing a metaclass, and I want an additional method to be called between __new__ and __init__.
如果我在__new__之前或__init__之后调用该方法,我可以写例如
If I were calling the method before __new__ or after __init__ I could write e.g.
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
,然后自己重现type .__ call__的功能.但是我担心键入可能会有些微妙.__call__我已经省略了,这将在实现我的元类时导致意外的行为.
and just reproduce the functionality of type.__call__ myself. But I'm afraid there might be some subtlety to type.__call__ I have omitted, which will lead to unexpected behavior when my metaclass is implemented.
我无法从__init__或__new__调用extraMethod,因为我希望我的元类的用户能够像在普通Python类中那样覆盖__init__和__new__,但仍要在extraMethod中执行重要的设置代码.
I cannot call extraMethod from __init__ or __new__ because I want users of my metaclass to be able to override __init__ and __new__ as in normal Python classes, but to still execute important set-up code in extraMethod.
谢谢!
推荐答案
如果您确实希望按照您所说的去做,我可以建议您使用以下解决方案:
If you really wish to do exactly what you said I can suggest you the following solution:
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()
此代码将产生以下结果:
This code will generate the following result:
new
custom_method
init
这篇关于默认类型__call__是否比调用__new__和__init__还要多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!