详解Python MetaClass
详解Python MetaClass
什么是MetaClass
原类(MetaClass)是Python中一种特殊的类。特殊之处在于它并不像普通类那样用来创建实例对象(instance),而是用来创建类(class)的。也就是说,原类是用来实例化类的。下图表明原类,类和实例对象之间的关系:
下面我们用一个最简单的例子来说明如何用原类来实例化类:
class PersonMeta(type):
def __new__(cls, clsname, superclasses, attributedict):
print("clsname:", clsname)
print("superclasses:", superclasses)
print("attrdict:", attributedict)
return super().__new__(cls, \
clsname, superclasses, attributedict)
class Person(object, metaclass=PersonMeta):
pass
print("Person is the instance of PersonMeta: %s" % isinstance(Person, PersonMeta))
print("Class Person's metaclass is: %s" % Person.__class__)
运行结果为:
clsname: Person
superclasses: (<class 'object'>,)
attrdict: {
'__module__': '__main__', '__qualname__': 'Person'}
Person is the instance of PersonMeta: True
Class Person's metaclass is: <class '__main__.PersonMeta'>
上述例子中,PersonMeta的__new__()函数接受3个参数:
- clsname:类型为string。是被实例化的类的名字,在这个例子中就是
Person
。 - superclasses:类型为tuple。是被实例化的类的父类,在这个例子中就是
object
。 - attributedict:类型为dictionary。是被实例化的类的属性。
Type类
通过上一节的例子,我们发现PersonMeta是继承自一个叫type
的类。type
类是一个特殊的原类,它是所有原类的超类。当创建原类时,如果不是需要继承某一个特定的原类的话,则默认继承自type
类。
用type实例化类
用type
类来实例化类的语法与我们通常定义类的语法略有不同,但效果是一样的。
# 通常定义类的方式
class Person1(object):
def __init__(self, age):
self._age = age
def get_age(self):
return self._age
# 用type定义类的方式
def init(self, age):
self._age = age
def get_age(self):
return self._age
# 第一个参数是被实例化类的名称。
# 第二个参数是被实例化类的父类。
# 第三个参数是被实例化类的属性。
Person2 = type('Person2', (object,), {
'__init__': init,
'get_age': get_age
})
p1 = Person1(15)
print("p1's age is: %d" % p1.get_age())
p2 = Person2(20)
print("p2's age is: %d" % p2.get_age())
输出结果:
p1's age is: 15
p2's age is: 20
动态创建类
用type
实例化类的一个好处是它可以动态的创建类:
class_names = ["Person1", "Person2"]
def init(self<