元类

元类

引入

一切都源自于一句话:一切皆为对象

如何得到对象

或者叫实例化

obj=调用类()

函数,模块,类本身都是对象

如果说类也是对象

class People:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say(self):
        print('%s:%s' %(self.name,self.name))

# People=调用类(。。。)

什么是元类

# 元类就是用来实例化产生类的类
# 关系:元类---实例化---->类(People)---实例化---->对象(obj)
# 查看内置的元类:
# 1、type是内置的元类
# 2、我们用class关键字定义的所有的类以及内置的类都是由元类type实例化产生
# print(type(People)) # <class 'type'>
# print(type(int))  # <class 'type'>

class机制分析

class关键字到底是怎么把类创造出来的?

类的三大特征

拿到类名

拿到基类

运行类体代码,拿到类的名称空间

# 类有三大特征:
# 1、类名
class_name="People"
# 2、类的基类
class_bases=(object,)
# 3、执行类体代码拿到类的名称空间
# 类的名称空间
class_dic={}

# 类体代码
class_body="""
def __init__(self,name,age):
    self.name=name
    self.age=age

def say(self):
    print('%s:%s' %(self.name,self.name))
"""
定义类的时候,类体代码会立即运行
运行过程中会把产生的类的名字放到名称空间里面去,
名称空间是一个字典

所以,类体放的是一个字符串,执行类体代码拿到类的名称空间

exec会执行类体代码,运行过程当中,会将产生的名字丢到class_dic中去
exec(class_body,{},class_dic)
print(class_dic) 
# {'__init__': <function __init__ at 0x000002961A3D2EA0>, 'say': <function say at 0x000002961A5AAB70>}

最后一步,class机制会调用元类

# 在造类时,没有指定元类,就用默认元类type
People=type(class_name,class_bases,class_dic) # 传三个参数
# class造类的执行过程
class_name="People"
class_bases=(object,)
class_dic={}
class_body="""
def __init__(self,name,age):
    self.name=name
    self.age=age

def say(self):
    print('%s:%s' %(self.name,self.name))
"""

exec(class_body,{},class_dic)
print(class_dic)
People=type(class_name,class_bases,class_dic)
print(People)  # <class '__main__.People'>

# 可以正常使用
obj = People('xiaoming',18)
print(obj.__dict__)  # {'name': 'xiaoming', 'age': 18}
# 学习了class机制底层的4个步骤,可以对哪些步骤进行操作
# 前三步骤没啥好操作的,都是最终交给内置元类type进行实例化
# 咱们要想方设法自定制元类,进而控制类的生成
People=Mymeta(class_name,class_bases,class_dic)

如何自定义元类来控制类的产生

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容