引入
Python中一切皆对象, 那么类本质上也是一个对象
一.什么是元类
类既然也是对象, 那么就应该有另一个类来实例化得到它, 实例化得到类的类就是元类
默认情況下, 元类是 type 这个类, 并且所有的类都是由元类实例化得到的, 包括他自己
1.先定义一个类来进行分析
class Immortal(object):
def __init__(self,name,age):
self.name = name
self.age = age
p = Immortal("太白",4555)
print(type(p)) # <class '__main__.Immortal'>
所有的对象都是通过 [类名] + ( ) 得到的, 也叫做实例化, p 对象就是由 Immortal 类实例化得到的
一切皆对象, 那么 Immortal 应该也是一个类实例化的结果, 于是我们可以推导出 元类+( ) ---> Immortal
print(type(Immortal)) # <class 'type'>
print(type(type)) # <class 'type'>
通过 type 函数我们发现 Immortal 的类就是 type 类, 并惊奇的发现 type 类的类是自身
由此我们可以推断出 : 元类实例化得到类, 类实例化得到对象(实例), 并且验证了所有类都是由type实例化得到的, 不信你试试
二.分析class关键字创建类的过程
上面我们都是使用 class 这个关键字来产生类的, class 关键字在帮我们创建类的时候必然调用了 Immortal = type( )
这种方法, 那么 type 里的参数应该是什么呢?
1.内置函数 exec 的用法
在分析 class 工作流程之前我们先来了解一下 exec 函数作为储备知识 : exec 有三个参数
- 第一个参数是包含的要执行的一系列 Python 代码(字符串格式)
- 第二个参数是全局名称空间 (字典形式), 默认为 globals( )
- 第三个参数是局部名称空间 (字典形式), 默认为 local( )
作用 : 可以将字符串里内容当做Python语句来执行, 并将期间产生的名字存放于局部名称空间中
msg = '''
name = "shawn"
age = 22
dic = {"sex":"man"}
def test():
print("I am shawn")
'''
globals_dic = {} # 全局名称空间
locals_dict = {} # 局部名称空间
exec(msg,globals_dic,locals_dict)
print(locals_dict)
# {'name': 'shawn', 'age': 22, 'dic': {'sex': 'man'}, 'test': <function test at 0x000002596D9BC4C8>}
print(locals_dict["name"]) # shawn
locals_dict["test"]() # I am shawn
2.调用 type + ( )来实现创建类
原来我们使用 class 来创建类, 其中必然调用了元类 type, type中需要传入三个参数, 这三个参数是类的三大组成部分 :
- 类名 : Immortal = type( )
- 父类们(基类们) : class_bases = (object , )
- 类的名称空间 : class_namespace (类的名称空间是执行类体代码而得到的)
接下来我们开始动手创建一个类了