回答

收藏

Python 中的metaclasses是什么?

技术问答 技术问答 213 人阅读 | 0 人回复 | 2023-09-12

在 Python 中,metaclasses我们用它们做什么?
% ~( c. b: l5 J9 P2 C, d                                                                ) O4 o2 E; x/ n, M, ?' W+ |# j" q5 K
    解决方案:                                                               
# G+ [" \# \5 L) O, e                                                                metaclass是类。类定义类的实例(即对象)行为模式,而元类定义类的行为模式。metaclass的实例。! C% M0 i5 q: S. V' q
虽然在 Python 你可以做到metaclass使用任何可调对象,但更好的方法是使其成为实际类本身。type是 Python 常见的元类。type它本身就是一个类它自己的类型。type完全用 Python重新创建类似的东西,但 Python 会作弊Python 创建自己的元类,你其实只想type.
, |, @" e! S5 Fmetaclass最常用作类工厂。当你通过调用类创建对象时,Python 将通过调用元类创建一个新当它执行时class语句时)。因此,结合常规__init__和__new__方法:元类允许你在创建类别时做额外的事情,比如用一些注册表注册新类别,或者用其他内容完全替换。
0 b0 r7 {% ^; e当class被执行的句子,Python首先执行的主体class声明是代码的正常块。生成的命名空间( dict)保存类属性。metaclass是通过查看类的基类(metaclass是继承、类别__metaclass__属性(如有)或__metaclass__确定全局变量。然后调用类的名称、基类和属性metaclass以实例化为例。
( H: N" G; N& g4 W1 N0 a# ^然而,metaclass实际上定义了一个类类型,而不仅仅是它的工厂,所以你可以用它们做更多的事情。例如,你可以metaclass定义普通方法。metaclass方法类似于类方法,因为它们可以在没有实例的类中调用,但它们不像类方法,因为它们不能在类实例中调用。type.__subclasses__()是type元类方法的一个例子。您还可以定义普通的魔法方法,例如__add__、__iter__和__getattr__,实现或改变类别的行为。$ D+ ]( h$ M/ b$ Z' s" j. k6 F
这是一个总结的例子:
3 V' b% s) x) w* Z1 n
    def make_hook(f):    """Decorator to turn 'foo' method into '__foo__'"""    f.is_hook = 1    return fclass MyType(type):    def __new__(mcls,name,bases,attrs):        if name.startswith('None):            return None        # Go over attributes and see if they should be renamed.        newattrs =         for attrname,attrvalue in attrs.iteritems()if getattr(attrvalue,'is_hook0):              newattrs['__%s__' % attrname] = attrvalue            else:                newattrs[attrname] = attrvalue        return super(MyType,mcls).__new__(mcls,name,bases,newattrs)    def __init__(self,name,bases,attrs):        super(MyType,self).__init__(name,bases,attrs)        # classregistry.register(self,self.interfaces)        print "Would register class %s now." % self    def __add__(self,other):        class AutoClass(self,other):            pass        return AutoClass        # Alternatively,to autogenerate the classname as well as the class:        # return type(self.__name__   other.__name__,(self,other),     def unregister(self):        # classregistry.unregister(self)        print "Would unregister class %s now." % selfclass MyObject:    __metaclass__ = MyTypeclass NoneSample(MyObject):    pass# Will print "NoneType None"print type(NoneSample),repr(NoneSample)class Example(MyObject):    def __init__(self,value):        self.value = value    @make_hook    def add(self,other):        return self.__class__(self.value   other.value)# Will unregister the classExample.unregister()inst = Example(10)# Will fail with an AttributeError#inst.unregister()print inst   instclass Sibling(MyObject):    passExampleSibling = Example   Sibling# ExampleSibling is now a subclass of both Example and Sibling (with no# content of its own) although it will believe it's called 'AutoClass'print ExampleSiblingprint ExampleSibling.__mro__
    7 |2 Y2 d$ K4 O
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则