【Python中的元类是什么(如何理解?有什么作用?如何使用元类?)】Python中的元类是什么?如何理解?有什么作用?如何使用元类?
元类是类的类。类定义了类的实例(即对象)在元类定义类的行为方式时的行为方式。类是元类的实例。
虽然在Python中你可以为元类使用任意的callables(比如Jerub节目),但更好的方法是让它成为一个真正的类本身。 type是Python中常用的元类。
type本身就是一个类,它是它自己的类型。你将无法在Python中重新创建纯类型的东西,但是Python会有所作为。要在Python中创建自己的元类,你真的只想子类化。
元类最常用作类工厂。当你通过调用类创建对象时,Python通过调用元类创建一个新类(当它执行’
class’
语句时)。结合常规的__init__和__new__方法,元类因此允许你在创建类时执行“额外的事情”,例如使用某些注册表注册新类或者完全替换其他类。
执行类语句时,Python首先执行类语句的主体作为正常的代码块。生成的命名空间(dict)保存了将要进行的类的属性。通过在待定类(如果有)的__metaclass__属性或__metaclass__全局变量中查看要被定义的类的基类(元类被继承)来确定元类。然后使用类的名称,基数和属性调用元类来实例化它。
但是,元类实际上定义了类的类型,而不仅仅是它的工厂,所以你可以用它们做更多的事情。例如,你可以在元类上定义常规方法。这些元类方法就像类方法一样,它们可以在没有实例的类上调用,但它们也不像类方法,因为它们不能在类的实例上调用。 type .__ subclasses __()是类型元类的方法示例。你还可以定义常规的“魔术”方法,如__add __,__ iter__和__getattr__,以实现或更改类的行为方式。
这是比特和碎片的汇总示例:
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_hook', 0):
newattrs['__%s__' % attrname] = attrvalue
else:
newattrs[attrname] = attrvaluereturn 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." % selfdef __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 = http://www.srcmini.com/value
@make_hook
def add(self, other):
return self.__class__(self.value + other.value)# Will unregister the class
Example.unregister()inst = Example(10)
# Will fail with an AttributeError
#inst.unregister()print inst + inst
class 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 ExampleSibling
print ExampleSibling.__mro__
推荐阅读
- Python中__str__和__repr__有什么区别(分别有什么作用?)
- Python如何将两个字典合并到一个表达式中(有哪些方式?)
- 如何按照值对Python字典排序(有几种方式和对应的实例?)
- 如何理解Python中if__name__==“__main__”(它是什么意思,有什么用?)
- CD Projekt Red承诺《赛博朋克2077》的发展紧缩不会像《巫师3》那样糟糕
- Blair Witch赶在万圣节前夕获得新的VR体验
- Ubisoft承诺《善与恶2》之外的更新承诺“游戏进展顺利”
- Anthems的残局仍然需要证明自己
- 揭露Anthem 2.0更新,如果正确拉开,可能没有人能像天空一样卷土重来