【问题标题】:Python3: correct usage of __init__ in metaclassPython3:在元类中正确使用 __init__
【发布时间】:2022-08-17 01:21:28
【问题描述】:

MyMeta.__init__ 实现如下。这个函数应该返回什么吗?它现在返回一个实例,这有什么影响吗?在元类中编写自定义__init__ 函数的用法示例是什么?

class MyMeta(type):

    def __new__(cls, name, bases, attr):
        print(\"***MyMeta.__new__ called\")
        instance = super(MyMeta, cls).__new__(cls, name, bases, attr)
        instance.v_new = \"v_new\"
        return instance

    def __init__(cls, name, bases, namespace, **kwargs):
        print(\"***MyMeta.__init__ called\")
        instance = super(MyMeta, cls).__init__(name, bases, namespace, **kwargs)
        return instance 


class AClass(metaclass=MyMeta):
    def __init__(self):
        print(\"@@@AClass.__init__ called\")


print(\"---> \")
a = AClass()
print(a.v_new)
  • 元类的实例是类。因此,当您定义一个将其用作元类的新类时,将调用 __init__() 方法。它就像任何其他 __init__() 方法一样被调用。实例已经创建——它在cls 参数中——并且没有使用返回值。
  • realpython.com/python-metaclasses 的元类中有一个使用__init__() 的示例。它在使用元类定义的每个类中设置一个类属性。

标签: python


【解决方案1】:
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')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-17
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    相关资源
    最近更新 更多