“MetaClass”, “__new__”, “cls” and “super” - what is the mechanism exactly?
我读过这样的文章:
但不知怎么的,我搞糊涂了。许多困惑,如:
什么时候,为什么我要做如下的事情?
1 2 | # Refer link1 return super(MyType, cls).__new__(cls, name, bases, newattrs) |
或
1 2 | # Refer link2 return super(MetaSingleton, cls).__call__(*args, **kw) |
号
或
1 2 | # Refer link2 return type(self.__name__ + other.__name__, (self, other), {}) |
超级如何工作?
什么是Link1中的类注册和注销,它是如何工作的?(我想这和辛格尔顿有关。我可能错了,因为我是C背景的。我的编码风格仍然混合了函数和OO)。
类实例化(子类、元类、super、类型)和方法调用的流程是什么?(
1 | metaclass->__new__, metaclass->__init__, super->__new__, subclass->__init__ inherited from metaclass |
。
)使用注释良好的工作代码(尽管第一个链接非常接近,但它不讨论cls关键字、super(..)和注册表)。最好是具有多重继承的示例。
P.S.:我把最后一部分作为代码,因为堆栈溢出格式正在转换文本
好吧,你已经在这里的混合中加入了很多概念!我将提出一些具体的问题。
一般来说,理解super、mro和metclasses会变得更加复杂,因为在过去几个版本的python中,这个棘手的领域发生了很多变化。
python自己的文档是一个非常好的参考,并且完全是最新的。有一篇IBMdeveloperWorks文章可以作为一个介绍,它采用了一种更基于教程的方法,但是请注意,它已经有5年的历史了,并且花了很多时间讨论元类的老式方法。
通过在类上(而不是在实例上)调用
托马斯对元类的描述非常好:
A metaclass is the class of a class.
Like a class defines how an instance
of the class behaves, a metaclass
defines how a class behaves. A class
is an instance of a metaclass.
号
在您给出的示例中,发生了以下情况:
对
cls)
这个例子使用的是元类执行一个单例。他是在元类,这样每当一个类实例被创建,他截取可以绕过实例如果已经存在,则创建(存储在
这显示了一种动态创建一个类。他来了附加提供的类的名称创建的类名,以及将其添加到类层次结构也是。
我不确定您要找的是哪种类型的代码示例,但下面是一个简短的示例,其中显示了元类、继承和方法解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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(object): __metaclass__ = MyMeta def __init__(self): super(A, self).__init__() print"A init" def meth(self): print"A.meth" class B(object): __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" >>> c_obj = C() meta: creating A (<type 'object'>,) meta: creating B (<type 'object'>,) meta: creating C (A, B) 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"mro.py", line 38, in <module> c_obj.meta_meth() AttributeError: 'C' object has no attribute 'meta_meth' |
下面是更务实的答案。
它很少重要
"什么是Python中的元类"。底线是,
1 2 3 | class X(object): pass type(X) == type |
"Python中元类的(具体)用例是什么?".底线。一个也没有。
"Python的超棒很漂亮,但你不能用它"。有趣的注释,但实用价值不大。您永远不需要解决复杂的多继承网络。使用一个明确的策略设计而不是多个继承很容易避免这个问题的发生。
下面是我在过去7年的Python编程中的经验。
一个类有一个或多个超类,形成从我的类到
"类"的概念是由名为
使用
然而,在所有子类情况下,您将使用
元类
元类的问题是:
每个对象都有一个对其类型定义的引用,或"类"。
class 本身也是一个对象。因此,
class 类型的对象引用了它的类型或"类"。"class"的"class"是一个元类。
因为"类"不是C++运行时对象,这在C++中是不存在的。它确实发生在爪哇,SimultTalk和Python。
元类定义类对象的行为。
90%的与类的交互是要求类创建一个新对象。
10%的时间,你将使用类方法或类变量(C++中的静态)或Java语言。
我发现了一些类级方法的用例。我几乎没有类变量的用例。我从未有过改变物体构造工作方式的情况。