设为首页 收藏本站
查看: 806|回复: 0

[经验分享] 简要介绍python的元编程的metaclass

[复制链接]

尚未签到

发表于 2017-5-4 07:13:17 | 显示全部楼层 |阅读模式
平时经常看到元编程、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了。先看一个例子
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>>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-372679-1-1.html 上篇帖子: Python: 50个能够满足所有需要的模块 下篇帖子: Python Lover(7)Twisted Basic
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表