《Python 核心技术与实战》 学习笔记 Day17 metaclass,是潘多拉魔盒还是阿拉丁神灯?

metaclass 的超越变形特性有什么用?

YAML是一个家喻户晓的 Python 工具,可以方便地序列化 / 逆序列化结构数据。YAMLObject 的一个超越变形能力,就是它的任意子类支持序列化和反序列化(serialization & deserialization)。比如说下面这段代码:

class Monster(yaml.YAMLObject):
  yaml_tag = u'!Monster'
  def __init__(self, name, hp, ac, attacks):
    self.name = name
    self.hp = hp
    self.ac = ac
    self.attacks = attacks
  def __repr__(self):
    return "%s(name=%r, hp=%r, ac=%r, attacks=%r)" % (
       self.__class__.__name__, self.name, self.hp, self.ac,      
       self.attacks)

yaml.load("""
--- !Monster
name: Cave spider
hp: [2,6]    # 2d6
ac: 16
attacks: [BITE, HURT]
""")

Monster(name='Cave spider', hp=[2, 6], ac=16, attacks=['BITE', 'HURT'])

print yaml.dump(Monster(
    name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT']))

# 输出
!Monster
ac: 16
attacks: [BITE, HURT]
hp: [3, 6]
name: Cave lizard

我们需要一个全局的注册器,让 YAML 知道,序列化文本中的 !Monster 需要载入成 Monster 这个 Python 类型。

Python 底层语言设计层面是如何实现 metaclass 的?

第一,所有的 Python 的用户定义类,都是 type 这个类的实例。
第二,用户自定义类,只不过是 type 类的call运算符重载。
第三,metaclass 是 type 的子类,通过替换 type 的call运算符重载机制,“超越变形”正常的类。

使用 metaclass 的风险

只有深入理解 metaclass 的本质,你才能用好 metaclass。

metaclass 仅仅是给小部分 Python 开发者,在开发框架层面的 Python 库时使用的。而在应用层,metaclass 往往不是很好的选择。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容