day38_元类
1、exec模块
Python内置模块 exec(code,global_dic,local_dic)
code = '''
global x
x = 10
y = 100
def func():
pass'''
global_dic = {}
local_dic = {}
exec(code,global_dic,local_dic)
2、元类
2.1 什么是元类
1、通过元类可以实例化出一个类,即类也是对象
2、type是所有类的元类
2.2 自定义元类
自定义元类,继承type,并派生出自己的属性方法
class Mytype(type):
def __init__(self, class_name, class_base, class_dict):
# 规定类名必须大写
print(f'调试信息:class_name:{class_name}')
if not class_name.istitle():
raise TypeError('类名不是驼峰体')
# 规定类中必须写注释
if not self.__doc__:
raise TypeError('类中需要添加注释')
# 复用父类属性,即调用元类,实例化一个类
super().__init__(class_name, class_base, class_dict)
# 调用元类Mytype时,即使用元类Mytype实例化对象,生成新类时触发__call__
def __call__(self, *args, **kwargs):
obj = object.__new__(self)
obj.__init__(*args, **kwargs)
return obj
# 派生__new__,控制创建对象(即类)过程
# def __new__(cls, *args, **kwargs):
# pass
2.3 定义类的两种方式
1、关键字class
2、使用元类type
class_name = 'Chinese'
base_name = (object,)
class_dic = {}
code = '''
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def speak(self):
print("speak Chinese...")
'''
exec(code, {}, class_dic) # 生成类的名称空间
Chinese = type(class_name, base_name, class_dic) # 元类实例化出类
print(Chinese.__dict__)
print(Chinese.__name__) # class_name
chinese = Chinese('hwm', 18)
print(chinese.__dict__)
'''
{'country': 'China', '__init__': <function __init__ at 0x0000022DCF5F5048>, 'speak': <function speak at 0x0000022DCF76B8B8>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None}
Chinese
{'name': 'hwm', 'age': 18}'''
3、通过metaclass=
指定自定义元类
# 此时指定了元类,所以不再默认继承object,需要指定继承
# metaclass=Mytype 自动实现Mytype(Foo,class_name,(object,),class_dict)
class Foo(object,metaclass=Mytype):
def __init__(self,x,y):
self.x = x
self.y = y
def f1(self):
print('from Foo.f1...')
foo = Foo(10,20)
print(foo.__dict__)
foo.f1()
'''
调试信息:class_name:Foo
{'x': 10, 'y': 20}
from Foo.f1...'''
4、区别
使用元类,可以通过元类代码控制类的创建规范,比如类名首字母大写,比如实例化对象的要求