基本概念
一个class 本身自己也是一个对象,是type类型的对象。
class -> create instance metaclass -> create class普通类,可以生成一个实例的类。
元类,可以生成一个普通类(class)的类;执行type方法,可以生成一个普通类。
type方法
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))类名-》我是谁父类-》我从哪里来包含的属性-》我能去哪里复制代码
My_create_class = type('My_create_clas',(),{})myinstance = My_create_class()print(type(myinstance))print(myinstance)print('+'*30)print(type(My_create_class))print(My_create_class)复制代码
# 运行结果<__main__.My_create_clas object at 0x03256CB0>++++++++++++++++++++++++++++++ 复制代码
metaclass属性
当为一个普通类指定metaclass属性时,会调用元类来生成该类。 该类,父类,模块层数,任何一个有改掉属性,都会先调用metaclass属性来生成该类
def upper_attr(class_name, class_parents, class_attr): print('metaclass work') attrs = ((name, value) for name, value in class_attr.items() if not name[0:2] == ('__')) upper_attrs = dict((name.upper(), value) for name, value in attrs) return type(class_name, class_parents, upper_attrs)class Foo(metaclass = upper_attr): bar = 'test'print(hasattr(Foo,'bar')) # Falseprint(hasattr(Foo,'BAR')) # True复制代码
从参考链接中作者的内容来看,虽然用函数的方式也能实现,但是使用metaclass实现OOP编程会好一些。
class Upper_attr(type): def __new__(cls, name, parents, dct): attrs = ((key,value) for key,value in dct.items() if not key[0:2] == '__') upper_attrs = dict((key.upper(),value) for key,value in attrs) return super(Upper_attr,cls).__new__(cls,name,parents,upper_attrs)class Foo(metaclass=Upper_attr): bar = 'test'# f = Foo()print(hasattr(Foo, 'bar')) # Falseprint(hasattr(Foo, 'BAR')) # True复制代码
从参考链中看到这几个字,恍然大悟
- 拦截类的创建
- 修改类
- 返回修改后的类
经过元类之后的类,就是我们普通使用的类了,可以用来创建实例。
对于简单的类, 参考链接给出了下面两种技术来修改类。 class decorators 装饰器
Monkey patching 猴子补丁参考: