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、区别

使用元类,可以通过元类代码控制类的创建规范,比如类名首字母大写,比如实例化对象的要求

posted @ 2019-11-04 14:32  W文敏W  阅读(91)  评论(0编辑  收藏  举报