什么是元类(metaclasses)?它们用于什么目的?
元类是Python中的一种高级概念,它们是创建类的类。在Python中,类也是对象,因此它们也可以被看作是对象的模板。元类允许您控制类的创建过程,例如修改类的属性或方法,或者添加新的属性和方法。
元类通常用于以下目的:
- 动态地创建类。您可以使用元类在运行时创建新的类,而不是在编写代码时静态地定义它们。
- 修改类的行为。您可以使用元类来修改类的行为,例如添加新的属性或方法,或者修改现有属性或方法的行为。
- 实现插件系统。您可以使用元类来实现插件系统,这样您就可以在不修改现有代码的情况下向应用程序添加新功能。
元类是类的类。类定义了类的实例(即对象)的行为,而元类定义了类的行为。类是元类的实例。
虽然在Python中可以使用任意可调用对象作为元类(如Jerub所示),但更好的方法是将其本身变成一个实际的类。type
是Python中通常的元类。type
本身就是一个类,它是它自己的类型。您无法完全用Python重新创建类似type
的东西,但Python有点作弊。要在Python中创建自己的元类,您真正想要做的只是继承type
。
元类最常用于类工厂。当您通过调用类来创建对象时,Python会在执行'class'语句时通过调用元类来创建一个新的类。与正常的__init__
和__new__
方法结合使用,元类因此允许在创建类时执行“额外的事情”,例如将新类注册到某些注册表中或将类替换为完全不同的东西。
当执行'class'语句时,Python首先将'class'语句的主体作为常规代码块执行。结果命名空间(字典)包含要创建的类的属性。元类是通过查看要创建的类的基类(元类是继承的)、要创建的类的__metaclass__
属性(如果有)或__metaclass__
全局变量来确定的。然后,使用要实例化的类的名称、基类和属性调用元类。
然而,元类实际上定义了一个type的类,而不仅仅是它的工厂,因此您可以使用它们做更多的事情。例如,您可以在元类上定义普通方法。这些元类方法类似于类方法,可以在没有实例的情况下调用类,但它们也不像类方法那样可以在类的实例上调用。type.__subclasses__()
是type
元类上的一个方法示例。您还可以定义普通的“魔术”方法,例如__add__
、__iter__
和__getattr__
,以实现或更改类的行为。
以下是一些零碎的例子:
def make_hook(f):
"""装饰器将'foo'方法变成'_\_foo\_\_'"""
f.is_hook = 1
return f
class MyType(type):
def __new__(mcls, name, bases, attrs):
if name.startswith('None'):
return None
# 遍历属性,看看它们是否应该被重命名。
newattrs = {}
for attrname, attrvalue in attrs.items():
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
# 或者,自动生成类名以及类:
# 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
# 将打印 "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)
# 将取消注册类
Example.unregister()
inst = Example(10)
# 将引发AttributeError错误
#inst.unregister()
print(inst + inst)
class Sibling(MyObject):
pass
ExampleSibling = Example + Sibling
# ExampleSibling现在是Example和Sibling的子类(没有自己的内容)
# 尽管它会认为它被称为'AutoClass'
print(ExampleSibling)
print(ExampleSibling.__mro__)
标签:__,Python,什么,class,元类,type,self
From: https://www.cnblogs.com/xiaomandujia/p/17747452.html