栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

儿童python教程164:Python MetaClass元类实现的底层原理

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

儿童python教程164:Python MetaClass元类实现的底层原理



要理解 MetaClass 的底层原理,首先要深入理解 Python 类型模型。本节将从以下 2 点对 Python 类型模型做详细的介绍。 1) 所有的 Python 的用户定义类,都是 type 这个类的实例 事实上,类本身不过是一个名为 type 类的实例,可以通过如下代码进行验证:

class MyClass:

  pass



instance = MyClass()

print(type(instance))

print(type(MyClass))
输出结果为:


可以看到,instance 是 MyClass 的实例,而 MyClass 是 type 的实例。 2) 用户自定义类,只不过是 type 类的 __call__ 运算符重载。 当定义完成一个类时,真正发生的情况是 Python 会调用 type 类的 __call__ 运算符。

简单来说,当定义一个类时,例如下面语句:

class MyClass:

  data = 1
Python 底层执行的是下面这段代码:

class = type(classname, superclasses, attributedict)
其中等号右边的 type(classname, superclasses, attributedict) 就是 type 的 __call__ 运算符重载,它会进一步调用下面这 2 个函数:

type.__new__(typeclass, classname, superclasses, attributedict)

type.__init__(class, classname, superclasses, attributedict)
以上整个过程,可以通过如下代码进行论证:

class MyClass:

  data = 1

 

instance = MyClass()

print(MyClass,instance)

print(instance.data)

MyClass = type('MyClass', (), {'data': 1})

instance = MyClass()



print(MyClass,instance)

print(instance.data)
运行结果为:

<__main__.MyClass object at 0x000001CB469F7400>
1
<__main__.MyClass object at 0x000001CB46A50828>
1

由此可见,正常的 MyClass 定义,和手工调用 type 运算符的结果是完全一样的。

总之,正是 Python 的类创建机制,给了 metaclass 大展身手的机会,即一旦把一个类型 MyClass 设置成元类 MyMeta,那么它就不再由原生的 type 创建,而是会调用 MyMeta 的 __call__ 运算符重载:

class = type(classname, superclasses, attributedict)

# 变为了

class = MyMeta(classname, superclasses, attributedict)
使用 metaclass 的风险 正如上面所看到的那样,metaclass 这样“逆天”的存在,会"扭曲变形"正常的 Python 类型模型,所以,如果使用不慎,对于整个代码库造成的风险是不可估量的。

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

建议初学者不要轻易尝试使用 mateclass。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/805937.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号