Python 核心技术与实战
景霄
Facebook 资深工程师
114324 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
Python 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?

扭曲变形Python类型模型
metaclass是type的子类
用户自定义类是type类的__call__运算符重载
类是type类的实例
metaclass实现
全局注册器
YAMLObject的实例
序列化/逆序列化结构数据
风险
Python底层实现
使用方法
用途
装饰器和metaclass的区别
metaclass
Python装饰器
思考题
本次总结
上次总结
总结

该思维导图由 AI 生成,仅供参考

你好,我是蔡元楠,极客时间《大规模数据处理实战》专栏的作者。今天我想和你分享的主题是:metaclass,是潘多拉魔盒还是阿拉丁神灯?
Python 中有很多黑魔法,比如今天我将分享的 metaclass。我认识许多人,对于这些语言特性有两种极端的观点。
一种人觉得这些语言特性太牛逼了,简直是无所不能的阿拉丁神灯,必须找机会用上才能显示自己的 Python 实力。
另一种观点则是认为这些语言特性太危险了,会蛊惑人心去滥用,一旦打开就会释放“恶魔”,让整个代码库变得难以维护。
其实这两种看法都有道理,却又都浅尝辄止。今天,我就带你来看看,metaclass 到底是潘多拉魔盒还是阿拉丁神灯?
市面上的很多中文书,都把 metaclass 译为“元类”。我一直认为这个翻译很糟糕,所以也不想在这里称 metaclass 为元类。因为如果仅从字面理解,“元”是“本源”“基本”的意思,“元类”会让人以为是“基本类”。难道 Python 的 metaclass,指的是 Python 2 的 Object 吗?这就让人一头雾水了。
事实上,meta-class 的 meta 这个词根,起源于希腊语词汇 meta,包含下面两种意思:
“Beyond”,例如技术词汇 metadata,意思是描述数据的超越数据;
“Change”,例如技术词汇 metamorphosis,意思是改变的形态。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Python中的metaclass是一种强大的语言特性,具有超越类和变形类的能力。本文通过介绍metaclass的用途、应用方法以及Python底层语言设计层面的实现原理,深入探讨了metaclass的特性和使用方法。作者以YAMLObject为例,展示了metaclass的超越变形特性,说明了其在动态序列化/逆序列化方面的优势。此外,还介绍了metaclass的使用方法,以及Python底层语言设计层面是如何实现metaclass的。通过深入浅出的讲解,读者能够快速了解metaclass的概念及其在Python中的应用。文章还提到了使用metaclass的风险,指出了其可能对整个代码库造成的不可估量的风险,因此在应用层并不是很好的选择。总结指出,深入理解metaclass的Python开发者才能用好metaclass,而对于初学者则是科普和警告:不要轻易尝试metaclass。文章通过解读YAML的源码,围绕metaclass的设计本意“超越变形”,解析了metaclass的使用场景和使用方法,深入到Python语言设计层面,搞明白了metaclass的实现机制。文章以黑魔法级别的语言特性来形容metaclass,强调了使用好metaclass可以实现神奇的特性,但使用不好可能会打开潘多拉魔盒。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(65)

  • 最新
  • 精选
  • 尘墨
    我尝试着自己写了一个例子,发现好像清晰多了,没有看懂的大家可以看一下 class Mymeta(type): def __init__(self, name, bases, dic): super().__init__(name, bases, dic) print('===>Mymeta.__init__') print(self.__name__) print(dic) print(self.yaml_tag) def __new__(cls, *args, **kwargs): print('===>Mymeta.__new__') print(cls.__name__) return type.__new__(cls, *args, **kwargs) def __call__(cls, *args, **kwargs): print('===>Mymeta.__call__') obj = cls.__new__(cls) cls.__init__(cls, *args, **kwargs) return obj class Foo(metaclass=Mymeta): yaml_tag = '!Foo' def __init__(self, name): print('Foo.__init__') self.name = name def __new__(cls, *args, **kwargs): print('Foo.__new__') return object.__new__(cls) foo = Foo('foo') 把上面的例子运行完之后就会明白很多了,正常情况下我们在父类中是不能对子类的属性进行操作,但是元类可以。换种方式理解:元类、装饰器、类装饰器都可以归为元编程(引用自 python-cook-book 中的一句话)。

    作者回复: 棒

    2019-06-20
    9
    93
  • KaitoShy
    yaml.load(""" --- !Monster name: Cave spider hp: [2,6] # 2d6 ac: 16 attacks: [BITE, HURT] """) 运行时报错,pyyaml版本PyYAML-5.1,将语句改成 yaml.load(""" --- !Monster name: Cave spider hp: [2,6] # 2d6 ac: 16 attacks: [BITE, HURT] """,Loader=yaml.Loader)即可,参见"https://github.com/yaml/pyyaml/issues/266"

    作者回复: 很好

    2019-06-19
    3
    5
  • TKbook
    一开始还以为我打开错专栏了。 目前看了好多解释metaclass的文章,感觉这一篇看起来最明了。

    作者回复: 谢谢

    2019-06-19
    2
    4
  • 隔壁家老鲍
    感觉入门了,不过还是有一些问题 @修饰符是在python里是怎么实现的呢 老师如果看到了可以给点意见么

    作者回复: 问题很好,修饰器的确和metaclass有很多相似之处

    2019-12-16
    1
  • jackstraw
    这代码跑都跑不通

    作者回复: 遇到什么问题?这些代码我都校验过

    2020-01-12
  • 奔跑的蜗牛
    看不懂了 😄
    2019-06-19
    5
    123
  • =_=
    基础不够,之前没接触过metaclass,这一讲读起来太费劲了
    2019-06-19
    40
  • 程序员人生
    装饰器像AOP,metaclass像反射机制
    2019-06-19
    1
    35
  • Hoo-Ah
    之前讲装饰器的时候讲到函数装饰器和类装饰器,而类装饰器就是在雷里面定义了__call__方法,之后在函数执行的时候会调用类的__call__方法。 在metaclass中重载了__call__方法,在使用metaclass实例化生成类的时候也是调用了__call__方法,从这方面来讲是很像。 要说不一样的话,一个是在执行层面,一个是在生成层面。 可以讲讲type和object的区别吗以及可以用一篇专栏讲讲python的魔术方法。
    2019-06-19
    27
  • 建强
    1.metaclass拦截了类的构造,类似于黑客,改变了类的行为,在某些场合可简化程序设计。 2.python装饰器:不会去改变类的行为,但通过装饰类,可以加强类的功能,通过不同的装饰器使类的功能更加丰富。
    2019-09-25
    21
收起评论
显示
设置
留言
65
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部