Python 是否使用默认类型.\uuuuu call\uuuuu做的不仅仅是call\uuuu new\uuuuuuu和\uuuuu init\uuuuu?

Python 是否使用默认类型.\uuuuu call\uuuuu做的不仅仅是call\uuuu new\uuuuuuu和\uuuuu init\uuuuu?,python,metaclass,Python,Metaclass,我正在编写一个元类,我希望在uuu new_uuuuuuuu和uuu init_uuuuuu之间调用一个额外的方法 如果我在uuu new uuuuuuuuuuuuuuuuuuuuuuuuuu之前或之后调用该方法,我可以编写 class Meta(type): def __call__(cls): ret = type.__call__() ret.extraMethod() 我的诱惑是写作 class Meta(type): def __cal

我正在编写一个元类,我希望在uuu new_uuuuuuuu和uuu init_uuuuuu之间调用一个额外的方法

如果我在uuu new uuuuuuuuuuuuuuuuuuuuuuuuuu之前或之后调用该方法,我可以编写

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
只需复制类型的功能即可。但我担心可能会有一些微妙的输入。我忽略了调用,这将导致在实现我的元类时出现意外行为

我不能从uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu或uuuuuuuuuuuuuuuuuuuuu


谢谢

如果你真的想完全按照你说的做,我可以建议你以下解决方案:

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

重写方法的标准实践是调用基类的重写方法(通常通过调用
super()
),这不足以确保类的
\uuuuu init\uuuuu()
\uu new\uuuuu()
代码得到执行吗除非从
cls返回的值为
cls,否则不会调用
。\uuuu new\uuuu(cls)