好的,您已经在这里混合了很多概念!我将提出您提出的一些具体问题。
一般来说,理解 super、MRO 和 metaclasses 变得更加复杂,因为在 Python 的最后几个版本中这个棘手的领域发生了很多变化。
Python's own documentation 是一个很好的参考,并且完全是最新的。有一个 IBM developerWorks article 作为介绍很好,它采用了更多基于教程的方法,但请注意它已有五年历史,并且花了很多时间谈论元类的旧式方法。
super 是您访问对象超类的方式。它比(例如)Java 的 super 关键字更复杂,主要是因为 Python 中的多重继承。正如Super Considered Harmful 解释的那样,使用super() 可能会导致您隐式使用一系列超类,其顺序由Method Resolution Order (MRO) 定义。
您可以通过在类(而不是实例)上调用 mro() 轻松查看类的 MRO。请注意,元类不在对象的超类层次结构中。
Thomas'对元类here的描述非常好:
元类是类的类。
就像一个类定义一个实例如何
类的行为,一个元类
定义类的行为方式。一类
是元类的一个实例。
在你给出的例子中,发生了什么:
-
正在拨打__new__
冒泡到下一件事
维修保养在这种情况下,super(MyType, cls) 将解析为 type;
调用 type.__new__ 让 Python
完成它的正常实例
创建步骤。
-
此示例使用元类
强制执行单例。他是
覆盖 __call__ 在
元类,这样每当一个类
创建实例,他拦截
那,并且可以绕过实例
如果已经有一个,则创建
(存储在cls.instance)。笔记
覆盖 __new__ 在
元类还不够好,
因为那只在什么时候被调用
创建类。覆盖
__new__ 在课堂上会起作用,
但是。
-
这显示了一种动态的方法
创建一个类。这是他
附加提供的类的名称
到创建的类名,和
将其添加到类层次结构中
也是。
我不确定您要查找的是哪种代码示例,但这里有一个简短的示例,展示了元类、继承和方法解析:
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'