Does the default type.__call__ do more than call __new__ and __init__?
我正在编写一个元类,我希望在uu new_uuu和uu init_uuu之间调用一个额外的方法。
如果我在"new"之前或"init"之后调用该方法,我可以编写例如
1 2 3 4 | class Meta(type): def __call__(cls): ret = type.__call__() ret.extraMethod() |
我的诱惑是写作
1 2 3 4 5 6 | class Meta(type): def __call__(cls): ret = cls.__new__(cls) ret.extraMethod() ret.__init__() return ret |
只需复制类型的功能。但我担心可能会有一些微妙的类型。uuu调用_uuuu我省略了,这将导致我的元类实现时的意外行为。
我不能从uu init_uuuu或uuu new_uuu调用ExtraMethod,因为我希望我的元类用户能够像在普通的python类中那样重写u init_uuuu和uuu new_uuuu,但仍然可以在ExtraMethod中执行重要的设置代码。
谢谢!
如果你真的想按照你说的做,我可以建议你以下的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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() |
此代码将生成以下结果:
1 2 3 | new custom_method init |