什么是python中的元类
程序员文章站
2022-11-05 11:50:17
所属网站分类: python高级 > 面向对象 作者:goodbody 原文链接: http://www.pythonheidong.com/blog/article/11/ 来源:python黑洞网 www.pythonheidong.com 元类是类的类。就像类定义了类的实例的行为一样,元类定义 ......
所属网站分类: python高级 > 面向对象
作者:goodbody
原文链接:
来源:python黑洞网
元类是类的类。就像类定义了类的实例的行为一样,元类定义了类的行为方式。类是元类的实例。
虽然在python中你可以为元类使用任意的callables,实际上更有用的方法是使它成为一个真正的类本身。
type是python中常用的元类。type它本身就是一个类,它是它自己的类型。
你将无法使用type在python中重新创建纯粹的东西。
元类最常用作类工厂。就像通过调用类创建类的实例一样,python通过调用元类创建了一个新类(当它执行'class'语句时)。结合__init__和__new__方法,元类因此允许您在创建类时执行“额外的事情”,例如使用某个注册表注册新类,或者甚至完全用其他内容替换类。
元类是通过查看待定类的基类(继承的元类),__metaclass__将要在类的属性(如果有)或__metaclass__全局变量来确定的。然后使用类的名称,基数和属性调用元类来实例化它。
但是,元类实际上定义了类的类型,而不仅仅是它的工厂,所以你可以用它们做更多的事情。例如,您可以在元类上定义常规方法。这些元类方法就像类方法一样,因为它们可以在没有实例的类上调用,但它们也不像类方法,因为它们不能在类的实例上调用。type.__subclasses__()是type元类的方法示例。您还可以定义常规的“魔术”方法,例如__add__,__iter__以及__getattr__实现或更改类的行为方式。
这是例示:
def make_hook(f): """decorator to turn 'foo' method into '__foo__'""" f.is_hook = 1 return f class 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] = 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." % self class myobject: __metaclass__ = mytype class 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 class example.unregister() inst = example(10) # will fail with an attributeerror #inst.unregister() print inst + inst class sibling(myobject): pass examplesibling = 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__
上一篇: 记得我上初中那会
下一篇: yagmail 邮箱的使用