# 元类就是制造类的类
# 元类在制造类时做的事情
"""
1.获取类的名字
2.获取类的父类
3.执行类体代码,拿到类的名称空间
4.调用元类type实例化一个类
"""
下面我们就解析一下class机制的底层运行原理
# class Person:
# def __init__(self):
# pass
#
# def __get__(self):
# pass
#
# def __str__(self):
# pass
# print(type(Person))
# # 要看到元类的执行步骤,我们需要使用到exec函数
# class_name = "Person"
# # 类的父类 要以元组的形式显示,因为类的父类可能不止一个
# class_base = (object,)
# # 类体(本质就是一堆字符串)
# class_baby = """
# def __init__(self):
# pass
#
# def __get__(self):
# pass
#
# def __str__(self):
# pass
# """
# # 执行类体代码拿到类的一个名称空间(类的名称空间就是(一个字典))
# class_dic = {}
# exec(class_baby, {}, class_dic) # 里面的空字典就相当于全局名称空间
# # exec做的事情就是执行字符串里面的代码,并将字符串里面的地址丢到class_dic这个字典里面去
# print(class_dic)
#
# # 调用元类
# Person = type(class_name, class_base, class_dic)
"""
不依赖class机制自己造一个类出来
第一步:造类名
第二步:造类的父类
第三步:造类的名称空间和类体
调用元类实现类的实例化
"""
# 造类名
class_name = "People"
# 造类的父类
class_base = (object,)
# 造空间
class_dic = {}
# 造类体代码
class_baby = """
def __init__(self):
pass
def get(self):
pass
"""
exec(class_baby, {}, class_dic) # exec做的事情就是将执行类体代码,
# 将执行类体代码得到的内存地址存储到class_dic里面,如果在执行过程中需要使用到全局名称空间,那么就会在空字典里面去找
# print(class_dic)
# print(type(class_name, class_base, class_dic))
# People = type(class_name, class_base, class_dic)
# People.name = "小阿牛"
# People.age = 18
# print(People.__dict__)
# print(People.name)
# 如何自定义元类来控制类的产生
练习
1.通过自定义元类规定类必须要添加一个注释:
class Mymeta(type):
def __init__(self, clas_name, clas_base, clas_dic):
if not clas_dic.get("__doc__"):
raise TypeError("没有写文档说明类的用途")
# print("run...")
# print(self)
# print(clas_name)
print(clas_base)
print(clas_dic)
class Person(object, metaclass=Mymeta):
"""
小阿牛
"""
def __init__(self, name, age):
self.name = name
self.age = age
2.规定类必须要大写类名,否则就报错:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能