python 的 metaclass

Python 是一种非常灵活的语言,这使得它具有很强的表达力,metaclass 也是这种强大表达力的一个体现。

啥是 metaclass 呢? meta- 这个词似乎这些年越来越流行,翻译成中文,一般是  元..., 比如元认知,元数据。“元什么” 一般表示的含义是 什么的什么, 元数据即数据的数据,元认知即认知的认知。metaclass 就是类的类。粗略的说,执行一个 metaclass 会得到一个新的 class, Python 内置的 type 就可以看成一个metaclass。

metaclass 有什么用呢?这个问题的答案和另一个问题的答案其实有些类似: decorator 有什么用呢? metaclass 和 decorator 都属于元编程。元编程,可以理解为让程序来写程序。当然,这里说的不是人工智能来写程序啊,只是一种固定模式的程序转换。让程序来写程序的目的,我感觉常见的一般是三个:一是减少重复性的 boilerplate, 这方面最典型的例子是 C 语言里的宏;第二是提供简洁易用的用户接口,比如python web 框架 Falsk 里面的装饰器 @app.route, 你不用它,也可以注册 url endpoint, 但是不如这个简洁;第三,一段代码的逻辑是动态的,但是一旦初始化完成之后代码逻辑就可以确定了,也很适合使用元编程,比如,一个函数内部两种逻辑,选择哪种依赖程序的某个配置,这个配置在编码阶段无法确定,但是一旦程序启动读取了配置之后,这个配置也是不会变的,这时就可以使用装饰器来动态定义该函数。

Python 中的 decorator 是可以装饰 class的, 那为什么还需要 metaclass 呢。PEP 3115 里做了解释, decorator 属于一种后处理,对一个类定义能施加的影响其实很有限,而metaclass 会深度介入一个类的创建过程。

metaclass 如何影响一个类的创建

python 官方的 Language Reference 中的 Data model一章有详细的说明,此处简单转述一下原理(忽略了一些细节)。

  1. 确定一个类的 metaclass, 如果一个类在定义时显示指定了 metaclass, 则使用该 metaclass, 否则使用 type() 作为其metaclass
  2. 准备namespace, 这个 namespace 是类内部的 namespace, 是一个类似字典的对象,用于保存类的各种属性。这个 namespace 是通过 metaclass.__prepare__(name, bases, **kwds) 得到。
  3. 在上述 namespace 中执行被定义的类的 body。
  4. 调用 metaclass(name, bases, namespace, **kwds) 创建被定义的类。

metaclass 示例

可参考 PEP3115 中的示例: https://www.python.org/dev/peps/pep-3115/#example

原文地址:https://www.cnblogs.com/a-distant-bright-star/p/11655534.html

时间: 2024-10-10 08:30:36

python 的 metaclass的相关文章

[python] 理解metaclass并实现一个简单ORM框架

metaclass 除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass. metaclass,直译为元类,简单的解释就是: 当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例. 但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类. 连接起来就是:先定义metaclass,就可以创建类,最后创建实例. 所以,metaclass允许你创建类或者修改类.换句话说,你可以把类看成是met

python class metaclass instance

>>> class CObj(object):... pass...>>> dir()['CObj', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']>>> cob = CObj>>> dir()['CObj', '__builtins__', '__doc__', '__loader__', '__name__', '__

python type metaclass

obj=Foo()##Foo类是MyType类的对象 所以先执行MyType的init  Foo()加括号执行MyType的call foo=type('Foo',(object,),{'say':lambda a:123}) ##所有类都是type类的对象 print(foo().say())

深刻理解Python中的元类(metaclass)

译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了985点的赞同点数,更有人评论说这段回复应该加入到Python的官方文档中去.而e-satis同学本人在Stack Overflow中的声望积分也高达6

Python type class metaclass

'type' 是 python built-in metaclass 其他继承自 ‘type’的class都可以是 Metaclass 子类可以继承父类的metaclass 然而 __metaclass__属性不能继承 __metaclass__可以定义成任何返回instance of 'type' callable __new__(cls, ...)  : create instance of cls __init__(self, ...) :instance already created

[转] 深刻理解Python中的元类(metaclass)

非常详细的一篇深入讲解Python中metaclass的文章,感谢伯乐在线-bigship翻译及作者,转载收藏. 本文由 伯乐在线 - bigship 翻译.未经许可,禁止转载!英文出处:stackoverflow.欢迎加入翻译组. 译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及

元类metaClass

metaClass 实现动态改变对象的能力,这点特别像python(metaClass),Python中类(不是元类)的概念借鉴于Smalltalk groovy demo: class Person { String name } // 添加自我介绍的行为 Person.metaClass.introduce << {println "I'm $name"} // 添加性别属性,默认为男(Male) Person.metaClass.sex = "Male&qu

metaclass(元类)的小探索

1.python 的metaclass 关于元类 在python中,有一经典解释文章,特别是注意到,而python中的基本元类就是type,type会根据传入参数的个数来决定发挥打印类型的函数功能或者发挥元类的作用.元类的自定义使用__metaclass__: (一)自定义metaclass 使用metaclass只需声明: __metaclass__ = something.. 放置元类的位置可以是任意的,python解释器进行查找元类的顺序这篇文章中已经详细说明:“如果Python没有找到_

Python的__init__, __new__魔法方法以及在__metaclass__元类中的使用

Python中类的实例化是由Python解释器先后调用__new__,__init__这两个魔法方法来完成的,前者用来完成实例化后的对象的"骨架"(比如,解释器会为对象分配地址,并返回一个指向该对象的引用值,该引用值会被紧接着传递给__init__函数),后者用" self.属性名 = 属性值 "这样的方式对实例化的对象进行"填充". 1.__new__ 在一个类(假设为类A)实例化出一个对象的过程中,__new__()方法先于__init__(