1. 什么是metaclass
metaclass元类,字面含义不好理解,在作者所见到的代码和业务中用到的不多。但是理解它之后其作用还是很有用的,毕竟有工具不用和不会是两码事。
Effective python这本书中介绍的元类:
高于类,而又超乎类的概念。可以python的class语句转换为元类,并令其在每次定义具体的类时,都提供独特的行为。
老实说,第一次看了这个说明之后我还一头雾水。在学习了之后,我的理解是:
元类,作用于普通类,在不改写被修改类体的前提下,可以在被作用的类定义时执行一些操作(比如验证、探查、修改等)。
注意:元类对子类的作用在子类定义时就起作用,而不是在创建对象时起作用。
2. 元类的作用
用元类来验证子类,修改子类属性/方法等。
3. 元类的使用方法
- 元类要继承type类,至于什么是type类,不是本文的重点,可以参考Python 的 type 和 object 之间是怎么一种关系?- 知乎。
- 要定义 __new__方法,并返回该方法要返回该类的一个实例对象,因为在使用元类创建类时,__new__方法会自动执行。
所以,元类定义及使用形式如下,在应用层面,我们主要关注的在于“元类完成的功能”这部分。
# 元类
class Meta(type):
def __new__(meta, name, bases, class_dict):
# 这四个参数参数名可以修改,但是参数个数是固定的
# meta: 即我们定义的Meta类
# name: 被修改的类类名
# bases: 被修改类的父类
# class_dict: 被修改类的所有属性、方法组成的字典
# 元类完成的功能
print(meta, name, bases, class_dict)
# 返回实例对象
return type.__new__(meta, name, bases, class_dict)
# 被修改的类,以mateclass形式使用元类
class One(object, mateclass=Meta):
pass
4. 使用实例
4.1 例子:元类修改子类属性
对于一个类,检查是否具有“test”属性,如果不存在,则自动创建该属性, 属性值为False.
实现代码如下:
# 元类
class CheckAttr(type):
def __new__(meta, name, bases, class_dict):
if 'test' not in class_dict:
class_dict['test'] = None
return type.__new__(meta, name, bases, class_dict)
# 被修改的类,不含有test属性
class AB(object, metaclass=CheckAttr):
pass
测试代码和输出结果如下:
# 测试代码
ab = AB()
print('--->', ab.test)
# 输出结果
---> False