代码之家  ›  专栏  ›  技术社区  ›  user1187968

调用元类的__init的默认代码__

  •  0
  • user1187968  · 技术社区  · 2 年前

    所以我有 super(MyMeta, cls).__new__(cls, name, bases, attr) 调用默认值 __new__ 作用我可以做类似的吗 __init__ ?调用默认值 __初始化__ 元类的函数。

    class MyMeta(type):
    
        def __new__(cls, name, bases, attr): # real signature unknown
            print("MyMeta.__new__ called")
            return super(MyMeta, cls).__new__(cls, name, bases, attr)
    
        def __init__(cls, name, bases, namespace, **kwargs):
            print("MyMeta.__init__ called")
            ### how to call the default __init__()?
    
    0 回复  |  直到 2 年前
        1
  •  0
  •   jsbueno    2 年前

    正确的方法是 super().__init__(name, bases, namespace, **kwargs) - super() 将自动包含第一个参数(cls)。 此外,无需将任何参数传递给 super() (因为里面没有这种需要 __new__ ):这些由运行时自动填写。

    做的时候 super().__new__(...) 必须显式地包含第一个参数(元类本身),因为 __新的__ 是一个静态方法,super不会自动添加任何参数。

    为了完整起见: __init__ ( type.__init__ )什么也不做,可能根本就不会被召唤。如果您包含 __初始化__ 方法,但是用调用它很重要 super() 以便您的元类可以在需要时与其他元类协同使用。

        2
  •  -1
  •   user1187968    2 年前
    class MetaClass(type):
        """
        Class is object. By default, "type" created the in memory class object.
        Instance is object. Class created the in memory instance object.
        """
        meta_counter = 0
    
        def __new__(cls, name, bases, attr):
            print("***MyMeta.__new__(): control class object creation")
            cls_object = super(MetaClass, cls).__new__(cls, name, bases, attr)
            return cls_object
    
        def __init__(cls, name, bases, namespace, **kwargs):
            print("***MyMeta.__init__() class-wide initializer")
            cls.cls_order = MetaClass.meta_counter
            MetaClass.meta_counter += 1
    
    
    class AClass(metaclass=MetaClass):
        def __init__(self):
            print("AClass.__init__()")
    
    
    class BClass(metaclass=MetaClass):
        pass
    
    
    class XClass:
        def __new__(cls, name, *args, **kwargs):
            print("ZClass.__new__(): constructor")
            instance = super(XClass, cls).__new__(cls, *args, **kwargs)
            return instance
    
        def __init__(self, *args, **kwargs):
            print("ZClass.__init__(): instance-wide initializer")
            self.id = 1
    
    
    print("\n\n---> ")
    a = AClass()
    print(a.cls_order)
    b = BClass()
    print(b.cls_order)
    
    print(MetaClass.meta_counter)
    
    print("\n\n***> ")
    XClass('my-name')