元类
什么是元类?
答:类的类。
如何理解?可以这样说,我们用类来创建一个实例对象如myObject = MyClass()
。事实上Python中的类也是对象(万物皆对象),所以类也需要通过类的类创建,如MyClass = MetaClass()
。这个类的类(MetaClass)就是元类。
元类从哪来
通常我们用type(object)
来获取一个对象的类型,如:
>>> type(512)
<class 'int'>
>>> type("zhong")
<class 'str'>
然而type()还有另一个用处:type(name, bases, dict) -> a new type
,也就是用来创建一个类。一般我们都是通过class
关键字来定义一个类:
class MyClass(object):
pass
但也可以用type动态创建一个类:
>>> MyClass = type("MyClass", (), {})
>>> myObject = MyClass()
其实type就是一个元类。Python中所有类都是通过type来创建的。我们可以通过__class__来验证:
>>> str.__class__
<class 'type'>
>>> int.__class__
<class 'type'>
>>> object.__class__
<class 'type'>
我们自己用class
定义出来的类也是如此:
>>> class MyClass(object):
pass
>>> myObject = MyClass()
>>> myObject.__class__.__class__
<class 'type'>
type的用法
函数接口:type(name, bases, dict)
- name:类名
- bases:基类,接收一个元组
- dict:绑定类的方法和属性
现在通过类比的方式来理解type()的使用。
第一种:利用class关键字定义类
class MyClass(object):
def __init__(self):
self.string = "this is a test class"
def print_str(self):
print(self.string)
if __name__ == "__main__":
myObject = MyClass()
print(myObject.string)
myObject.print_str()
# 输出:
#this is a test class
#this is a test class
第二种:利用type创建类
string = "this is a test class"
def print_str(self):
print(self.string)
MyClass = type(
"MyClass",
(object,),
dict(string=string, print_str=print_str))
if __name__ == "__main__":
myObject = MyClass()
print(myObject.string)
myObject.print_str()
# 输出:
#this is a test class
#this is a test class
创建类的过程
当我们用如下方法
class MyClass(object):
pass
Python做了这样的操作:(1)在MyClass中寻找metaclass,如果存在,用它来创建名MyClass的类对象;(2)如果不存在,就去父类(这里是object)中找;(3)最后都没找到,利用Python内置的type()创建这个类对象
注: 在Python2中,如果没在父类中找到metaclass会去模块层次中寻找,但似乎Pythony3里取消了,这里留疑
metaclass的使用
比如,我们想给自己定义的类添加author属性,即所有实例化的对象都可以执行语句:a.author
来获取作者信息,实现代码如下:
def upper_attr(name, bases, attrs):
# 增加author信息
attrs.update({"author":"Guan"})
# 返回一个类的类
return type(name, bases, attrs)
# metaclass的使用方法
class MyClass(object, metaclass=upper_attr):
pass
if __name__ == "__main__":
myObj = MyClass()
print(myObj.author)
# 输出:
#Guan
事实上,更建议metaclass对接一个自定义的元类,而不是函数
# 需要继承自type
class MyMetaClass(type):
def __new__(cls, name, bases, attrs):
attrs.update({"author":"Guan"})
return super().__new__(cls, name, bases, attrs)
class MyClass(object, metaclass=MyMetaClass):
pass
if __name__ == "__main__":
myObj = MyClass()
print(myObj.author)
# 输出
#Guan
元类的作用
元类的主要目的是为了当创建类时能够自动地改变类。正如我前边的列子,创建的每一个类都能够自动添加author属性。
还不快抢沙发