gpt4 book ai didi

python - "MetaClass"、 "__new__"、 "cls"和 "super"- 究竟是什么机制?

转载 作者:IT老高 更新时间:2023-10-28 22:12:28 32 4
gpt4 key购买 nike

我读过这样的帖子:

  1. What is a metaclass in Python?
  2. What are your (concrete) use-cases for metaclasses in Python?
  3. Python's Super is nifty, but you can't use it

但不知何故,我感到困惑。许多困惑,例如:

我何时以及为什么必须执行以下操作?

# Refer link1
return super(MyType, cls).__new__(cls, name, bases, newattrs)

# Refer link2
return super(MetaSingleton, cls).__call__(*args, **kw)

# Refer link2
return type(self.__name__ + other.__name__, (self, other), {})

super 究竟是如何工作的?

什么是链接 1 中的类注册和取消注册,它是如何工作的? (我认为这与 singleton 有关。我可能是错的,来自 C 背景。我的编码风格仍然是函数式和 OO 的混合体。

类实例化(子类、元类、父类(super class)、类型)和方法调用的流程是什么(

metaclass->__new__, metaclass->__init__, super->__new__, subclass->__init__ inherited from metaclass

) 具有良好注释的工作代码(虽然第一个链接非常接近,但它没有谈论 cls 关键字和 super(..) 和注册表)。最好是多继承的例子。

P.S.:我将最后一部分制作为代码,因为堆栈溢出格式正在转换文本 metaclass->__new__到元类->

最佳答案

好的,您已经在这里混合了很多概念!我将提出您提出的一些具体问题。

一般来说,理解 super、MRO 和 metaclasses 变得更加复杂,因为在 Python 的最后几个版本中这个棘手的领域发生了很多变化。

Python's own documentation是一个很好的引用,并且完全是最新的。有一个IBM developerWorks article这很好作为介绍,并采用更多基于教程的方法,但请注意,它已有五年历史,并且花了很多时间谈论元类的旧式方法。

super 是您访问对象父类(super class)的方式。它比(例如)Java 的 super 关键字更复杂,主要是因为 Python 中的多重继承。如Super Considered Harmful解释说,使用 super() 会导致您隐式使用父类(super class)链,其顺序由 Method Resolution Order 定义。 (MRO)。

您可以通过在类(而不是实例)上调用 mro() 轻松查看类的 MRO。请注意,元类不在对象的父类(super class)层次结构中。

Thomas ' 元类的描述 here非常好:

A metaclass is the class of a class.Like a class defines how an instanceof the class behaves, a metaclassdefines how a class behaves. A classis an instance of a metaclass.

在你给出的例子中,发生了什么:

  1. 正在调用 __new__冒泡到下一件事维修保养在这种情况下,super(MyType, cls) 将解析为 type;调用 type.__new__ 让 Python完成它的正常实例创建步骤。

  2. 这个例子使用了元类强制执行单例。他是覆盖 __call__ 在元类,这样每当一个类创建实例,他拦截那,并且可以绕过实例如果已经有一个,则创建(存储在 cls.instance 中)。笔记覆盖 __new__ 在元类还不够好​​,因为那只在什么时候被调用创建。覆盖类上的 __new__ 会起作用,但是。

  3. 这显示了一种动态的方法创建一个类。这是他附加提供的类的名称到创建的类名,和将其添加到类层次结构中也是。

我不确定您要查找的代码示例,但这里有一个简短的示例,展示了元类、继承和方法解析:

print('>>> # Defining classes:')

class MyMeta(type):
def __new__(cls, name, bases, dct):
print("meta: creating %s %s" % (name, bases))
return type.__new__(cls, name, bases, dct)

def meta_meth(cls):
print("MyMeta.meta_meth")

__repr__ = lambda c: c.__name__

class A(metaclass=MyMeta):
def __init__(self):
super(A, self).__init__()
print("A init")

def meth(self):
print("A.meth")

class B(metaclass=MyMeta):
def __init__(self):
super(B, self).__init__()
print("B init")

def meth(self):
print("B.meth")

class C(A, B, metaclass=MyMeta):
def __init__(self):
super(C, self).__init__()
print("C init")

print('>>> c_obj = C()')
c_obj = C()
print('>>> c_obj.meth()')
c_obj.meth()
print('>>> C.meta_meth()')
C.meta_meth()
print('>>> c_obj.meta_meth()')
c_obj.meta_meth()

示例输出(使用 Python >= 3.6):

>>> # Defining classes:
meta: creating A ()
meta: creating B ()
meta: creating C (A, B)
>>> c_obj = C()
B init
A init
C init
>>> c_obj.meth()
A.meth
>>> C.meta_meth()
MyMeta.meta_meth
>>> c_obj.meta_meth()
Traceback (most recent call last):
File "metatest.py", line 41, in <module>
c_obj.meta_meth()
AttributeError: 'C' object has no attribute 'meta_meth'

关于python - "MetaClass"、 "__new__"、 "cls"和 "super"- 究竟是什么机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/395982/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com