什么是python中的元类

匿名 (未验证) 提交于 2019-12-02 22:11:45

面向对象


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

虽然在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__




易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!