python 元类

188 阅读2分钟

基本概念

一个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)
# 运行结果
<class '__main__.My_create_clas'>
<__main__.My_create_clas object at 0x03256CB0>
++++++++++++++++++++++++++++++
<class 'type'>
<class '__main__.My_create_clas'>

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'))  # False
print(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')) # False
print(hasattr(Foo, 'BAR')) # True

从参考链中看到这几个字,恍然大悟

  • 拦截类的创建
  • 修改类
  • 返回修改后的类

经过元类之后的类,就是我们普通使用的类了,可以用来创建实例。

对于简单的类, 参考链接给出了下面两种技术来修改类。 class decorators 装饰器
Monkey patching 猴子补丁

参考: 理解Python中的元类(metaclass)