【问题标题】:Implicit call of a base metaclass init function in Python 3Python 3 中基元类初始化函数的隐式调用
【发布时间】:2021-03-17 17:39:21
【问题描述】:

下面有代码:

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)

在 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 在脚本初始化时被隐式调用(两次_

在 python 3 中,根本不会打印任何内容。假设您无法更改 BaseMetaService 类,您将如何修改 Proxy 类以便在 Python 中看到类似于上述输出的输出3?谢谢。

【问题讨论】:

    标签: python metaprogramming metaclass


    【解决方案1】:

    问题是__metclass__ 在 Python 3 中不再有任何特殊状态。通常,您可以在类定义语句中像参数一样指定元类:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2018-03-15
      相关资源
      最近更新 更多