元类

元类

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 @ 2019-12-14 14:41  Mr沈  阅读(159)  评论(0编辑  收藏  举报