简要介绍python的元编程的metaclass
具体请点击:http://www.verydemo.com/demo_c122_i20324.html
平时经常看到元编程、DSL这样的字眼,它到底是什么意思?
我的理解来看。元编程就是“代码生成器”,你可以通过一些代码生成另一些代码(动态地、按需的)。DSL则是domain special language:为了解决某个问题而发明的语言,比如HTML SQL YACC,它的反面是C JAVA Python这些通用语言。与DSL经常提到的是ruby,为什么说ruby可以DSL呢?因为它语法丰富,支持各种简写,lamba,闭包,block等等,通过自定义的一套高级API从而实现一门特定领域的方言。这种方言是可以交给客户写的。
python中元编程的目标是:动态生成需要的类class。我们知道class实例化后就是instance,而python中的metaclass实例化后就是class了。先看一个例子
输出结果是:
通过修改__new__里面的attrs就可以更改类的属性
python类在初始化的时候,经历了两个阶段,第一个阶段是分配空间__new__(),第二个阶段是初始化值__init__()。当类被创建时,python2会首先寻找__metaclass__是否存在,如果存在则调用__metaclass__。如果此类没定义__metaclass__就去看父类,父类没有就去模块里找(全局变量__metaclass__),包里再没有就把__metaclass__ = type作为类的metaclass。而python3先看自己metaclass有没有定义,如果没有就看父类,父类没有就用type
再介绍下__new__中各个参数的意思:cls代表调用__new__函数的class,name代表对象的__name__值,也就是名称,parents代表对象的父类元组,attrs代表类的属性字典。
metaclass功能就是这么简单,一般来说是用不上的,除非要大批量的修改类的属性。其实python本身就是动态语言,在运行时就可以更改属性。而且decorator也可以很好的修改调用对象前后的行为。所以metaclass了解就行。
metaclass还有一些比较边边角角的知识点,比如说MyMeta这里还会引入一个__prepare__函数:
这个函数还要在__new__函数调用之前调用,这个函数必须返回一个用于存放类属性(namespace)的数据结构,默认情况下就是字典类型了。我在这里直接就把kwargs返回就可以,没问题的,极端点,return {}都是可以的。这里可以玩一下,比如说
你会发现整个类中都会被添加xx这个属性……
最后附上几个小知识点:
我的理解来看。元编程就是“代码生成器”,你可以通过一些代码生成另一些代码(动态地、按需的)。DSL则是domain special language:为了解决某个问题而发明的语言,比如HTML SQL YACC,它的反面是C JAVA Python这些通用语言。与DSL经常提到的是ruby,为什么说ruby可以DSL呢?因为它语法丰富,支持各种简写,lamba,闭包,block等等,通过自定义的一套高级API从而实现一门特定领域的方言。这种方言是可以交给客户写的。
python中元编程的目标是:动态生成需要的类class。我们知道class实例化后就是instance,而python中的metaclass实例化后就是class了。先看一个例子
class MyMeta(type): def __new__(cls, name, parents, attrs): print("new info: ", cls, name, parents, attrs) attrs['abcde'] = 'fghijk' return type.__new__(cls, name, parents, attrs) class C(metaclass=MyMeta): pass print(C.abcde)
输出结果是:
引用
fghijk
通过修改__new__里面的attrs就可以更改类的属性
python类在初始化的时候,经历了两个阶段,第一个阶段是分配空间__new__(),第二个阶段是初始化值__init__()。当类被创建时,python2会首先寻找__metaclass__是否存在,如果存在则调用__metaclass__。如果此类没定义__metaclass__就去看父类,父类没有就去模块里找(全局变量__metaclass__),包里再没有就把__metaclass__ = type作为类的metaclass。而python3先看自己metaclass有没有定义,如果没有就看父类,父类没有就用type
再介绍下__new__中各个参数的意思:cls代表调用__new__函数的class,name代表对象的__name__值,也就是名称,parents代表对象的父类元组,attrs代表类的属性字典。
metaclass功能就是这么简单,一般来说是用不上的,除非要大批量的修改类的属性。其实python本身就是动态语言,在运行时就可以更改属性。而且decorator也可以很好的修改调用对象前后的行为。所以metaclass了解就行。
metaclass还有一些比较边边角角的知识点,比如说MyMeta这里还会引入一个__prepare__函数:
#官方文档说要是classmethod类型 @classmethod def __prepare__(self, *args, **kwargs): print("__prepare__ called") # return type.__prepare__(self, *args, **kwargs) return kwargs
这个函数还要在__new__函数调用之前调用,这个函数必须返回一个用于存放类属性(namespace)的数据结构,默认情况下就是字典类型了。我在这里直接就把kwargs返回就可以,没问题的,极端点,return {}都是可以的。这里可以玩一下,比如说
return {'xx': 'yy'}
你会发现整个类中都会被添加xx这个属性……
最后附上几个小知识点:
#可以使用type动态创建一个类 myclass = type("MyClass", (), {}) print(myclass) s = super(myclass, myclass()) #super其实返回一个super object print(s) #输出结果是: <super: <class 'MyClass'>, <MyClass object>>
相关推荐
夜斗不是神 2020-11-17
huavhuahua 2020-11-20
Yasin 2020-11-16
xiaoseyihe 2020-11-16
千锋 2020-11-15
diyanpython 2020-11-12
chunjiekid 2020-11-10
wordmhg 2020-11-06
YENCSDN 2020-11-17
lsjweiyi 2020-11-17
houmenghu 2020-11-17
Erick 2020-11-17
HeyShHeyou 2020-11-17
以梦为马不负韶华 2020-10-20
lhtzbj 2020-11-17
pythonjw 2020-11-17
dingwun 2020-11-16
lhxxhl 2020-11-16