元类

元类

1、exec

exec是python内置函数,可以将字符串的代码添加到自定义的名称空间中

语法:exec(字符串形式的python代码,全局名称空间,局部名称空间)

字符串形式的代码是加载到自定义的名称空间中,可以在字符串名称空间中使用global将一些属性和方法引入自定义的全局名称空间中

名称空间是一个字典形式的

# 字符串形式的代码
code = '''

x = 10
y = 20

def func():
	pass
def __init__():
	pass
'''

# 自定义的全局名称空间
global_dic = {'z':100}

# 自定义的局部名称空间
local_dic = {'t':300}
print(global_dic)
print(local_dic)
exec(code,global_dic,local_dic)
print(code)
print(global_dic)
print(local_dic)  # {'t': 300, 'x': 10, 'y': 20, 'func': <function func at 0x00000123A6602558>, '__init__': <function __init__ at 0x00000123A6602B88>}

2、元类

1、什么是元类

类的类就是type,type就是元类

type是python内置的元类

2、为什么要使用元类

元类可以控制类的创建过程,可以通过自定义的一个元类来控制创建的类的过程

3、怎么使用元类

# 自定义一个元类
class MyMetaClass(type):
    # 控制类的创建,重写type中的__init__
    def __init__(self, class_name, class_base, class_dict):
        # 控制创建类时首字母必须大写
        if not class_name.istitle():
            raise NameError('类的首字母必须要大写!!')
        # 控制创建类时必须要写注释
        if not class_dict.get('__doc__'):
            raise TypeError('定义必须要写注释!!')
        # 必须要将重新定义__init__返回给type中的__init__
        super().__init__(class_name, class_base, class_dict)


# 使用自定义元类(类名,基类,类的名称空间)来产生类
class User(object, metaclass=MyMetaClass):
    '''
    注释必须要写啊!
    '''
    def __init__(self):
        pass
    x = 10

# 调用类产生对象
obj = User()
print(obj)
为什么调用类就会产生一个空对象:内部执行了__ new__

为什么一定会执行__ new__:其实是type内部调用了一次__call__,由__call__来帮你调用__new__产生新的空对象,所有元类中的__call__ 就是创建类的过程
class MyMetaClass(type):
    def __init__(self,class_name,class_base,class_dict):
        if not class_name.istitle():
            raise NameError('类定义必须首字母大写')
        super().__init__(class_name,class_base,class_dict)
    # 模拟__call__创建类的过程
    def __call__(self,*args,**kwargs):
        # 创造一个新空对象
        obj = object.__new__(self)
        # 调用类时,__call__会立马调用user.__init__,并且会将obj连同参数一并传入__init__
        self.__init__(obj,*args,**kwargs)
        # 返回一个真正的对象
        return obj
posted @   Mr沈  阅读(159)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示

目录