在 Python 3 中隐式调用基本元类初始化函数

Implicit call of a base metaclass init function in Python 3

有以下代码:

class BaseMeta(type):
    def __init__(self, cls_name, cls_bases, cls_dict):
        super(BaseMeta, self).__init__(cls_name, cls_bases, cls_dict)
        print("BaseMeta init")
        print(cls_dict)

class Proxy():
    class __metaclass__(BaseMeta, type):
        def __new__(cls, name, bases, dict):
            return type.__new__(cls, name, bases, dict)

        def __init__(cls, name, bases, dict):
            print("Proxy init")
            BaseMeta.__init__(cls, name, bases, dict)

class Service(Proxy):
    def some_endpoint(self, a):
        print(a)

当 运行 in Python 2 时,输出类似于:

Proxy init
BaseMeta init
{'__module__': '__main__', '__metaclass__': <class '__main__.__metaclass__'>}
Proxy init
BaseMeta init
{'some_endpoint': <function some_endpoint at 0x8011e35d0>, '__module__': '__main__'}

BaseMeta init 在脚本 init 上隐式调用 (twice_

在python3中,根本不会打印任何东西。假设你不能改变BaseMetaServiceclasses,你将如何修改Proxy class 所以你可以在 Python 3 中看到类似于上面输出的输出?谢谢

问题是 __metclass__ 在 Python 中不再有任何特殊地位 3. 通常,您在 class 定义中像参数一样指定元 class声明:

class Foo(metaclass=FooMeta):
    ...

你可以这样做:

class BaseMeta(type):
    def __init__(self, cls_name, cls_bases, cls_dict):
        super(BaseMeta, self).__init__(cls_name, cls_bases, cls_dict)
        print("BaseMeta init")
        print(cls_dict)

class ProxyMeta(BaseMeta):
    def __new__(cls, name, bases, dict):
        return type.__new__(cls, name, bases, dict)
    def __init__(cls, name, bases, dict):
        print("Proxy init")
        BaseMeta.__init__(cls, name, bases, dict)

class Proxy(metaclass=ProxyMeta):
    pass

class Service(Proxy):
    def some_endpoint(self, a):
        print(a)