"MetaClass","__ new __","cls"和“超级" -确切的机制是什么? [英] "MetaClass", "__new__", "cls" and "super" - what is the mechanism exactly?

查看:71
本文介绍了"MetaClass","__ new __","cls"和“超级" -确切的机制是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了类似这样的帖子:

I have read posts like these:

  1. 什么是Python中的元类?
  2. 您的(具体)用例是什么python中的元类?
  3. Python的Super很漂亮,但您不能使用它
  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

但是我莫名其妙地感到困惑.许多混乱,例如:

But somehow I got confused. Many confusions like:

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

When and why would I have to do something like the following?

# 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到底如何工作?

How does super work exactly?

什么是link1中的类注册表和注销,它如何工作? (我认为这与 singleton 有关.我可能是错的,因为C背景我的编码风格仍然是功能和OO的混合.

What is class registry and unregistry in link1 and how exactly does it work? (I thought it has something to do with singleton. I may be wrong, being from C background. My coding style is still a mix of functional and OO).

类实例化(子类,元类,超级类,类型)和方法调用(

What is the flow of class instantiation (subclass, metaclass, super, type) and method invocation (

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

)带有经过注释的工作代码(尽管第一个链接非常接近,但是它没有讨论cls关键字以及super(..)和注册表).最好是具有多重继承的示例.

) with well-commented working code (though the first link is quite close, but it does not talk about cls keyword and super(..) and registry). Preferably an example with multiple inheritance.

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

P.S.: I made the last part as code because Stack Overflow formatting was converting the text metaclass->__new__ to metaclass->new

推荐答案

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

OK, you've thrown quite a few concepts into the mix here! I'm going to pull out a few of the specific questions you have.

通常,对super,MRO和metclasss的理解要复杂得多,因为在最近的几个Python版本中,这个棘手的领域进行了很多更改.

In general, understanding super, the MRO and metclasses is made much more complicated because there have been lots of changes in this tricky area over the last few versions of Python.

Python自己的文档是非常好的参考,并且是最新的.有 IBM developerWorks文章,作为介绍和采用了更多基于教程的方法,但是请注意它已经有五年历史了,并且花了大量时间谈论元类的旧式方法.

Python's own documentation is a very good reference, and completely up to date. There is an IBM developerWorks article which is fine as an introduction and takes a more tutorial-based approach, but note that it's five years old, and spends a lot of time talking about the older-style approaches to meta-classes.

super 是访问对象超类的方式.它比(例如)Java的super关键字更复杂,主要是由于Python中的多重继承.正如超级被认为有害所述,使用super()可能会隐式使用一系列超类,其顺序由方法解析顺序(MRO)定义.

super is how you access an object's super-classes. It's more complex than (for example) Java's super keyword, mainly because of multiple inheritance in Python. As Super Considered Harmful explains, using super() can result in you implicitly using a chain of super-classes, the order of which is defined by the Method Resolution Order (MRO).

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

You can see the MRO for a class easily by invoking mro() on the class (not on an instance). Note that meta-classes are not in an object's super-class hierarchy.

Thomas 对元类的描述

Thomas' description of meta-classes here is excellent:

元类是类的类. 就像一个类定义了一个实例 类的行为,元类 定义类的行为方式.一类 是元类的实例.

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.

在您提供的示例中,正在发生的事情:

In the examples you give, here's what's going on:

  1. 正在呼叫__new__ 冒泡到下一件事 MRO.在这种情况下,super(MyType, cls)将解析为type; 调用type.__new__可以让Python 完成它是正常情况 创建步骤.

  1. The call to __new__ is being bubbled up to the next thing in the MRO. In this case, super(MyType, cls) would resolve to type; calling type.__new__ lets Python complete it's normal instance creation steps.

此示例使用元类 强制执行单例.他是 覆盖__call__ 元类,这样每当一个类 创建实例,他拦截 并可以绕过实例 创建,如果已经有一个 (存储在cls.instance中).笔记 覆盖__new__的 元类不够好, 因为只有在 创建 class .覆写 在班上的__new__会起作用, 但是.

This example is using meta-classes to enforce a singleton. He's overriding __call__ in the metaclass so that whenever a class instance is created, he intercepts that, and can bypass instance creation if there already is one (stored in cls.instance). Note that overriding __new__ in the metaclass won't be good enough, because that's only called when creating the class. Overriding __new__ on the class would work, however.

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

This shows a way to dynamically create a class. Here's he's appending the supplied class's name to the created class name, and adding it to the class hierarchy too.

我不确定您要查找哪种代码示例,但这是一个简短的示例,显示了元类,继承和方法解析:

I'm not exactly sure what sort of code example you're looking for, but here's a brief one showing meta-classes, inheritance and method resolution:

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'

这篇关于"MetaClass","__ new __","cls"和“超级" -确切的机制是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆