`

python元类

 
阅读更多

原文地址: http://www.voidspace.org.uk/python/articles/five-minutes.shtml

日期: 16 September, 2008.

译者:赖勇浩( http://blog.csdn.net/lanphaday

  “元类的魔幻变化比   99%  的用户所担心的更多,当你搞不懂是否真的需要用它的时候,就是不需要。”

—Tim Peters

本文源于在   PyCon UK 2008   上的一个快速演讲。

元类被称为   Python  中的“深奥的巫术”。尽管你需要用到它的地方极少(除非你基于   zope  编程),可事实上它的基础理论其实令人惊讶地易懂。

一切皆对象

  • 一切皆对象
  • 一切都有类型
  •   class ”和“ type ”之间本质上并无不同
  • 类也是对象
  • 它们的类型是   type

以前,术语   type  用于内置类型,而术语   class  用于用户定义的类,但自   Pythoon 2.2  以来“ class ”和“ type ”本质上并无不同。

对于旧风格( old-style )类的类型是   types.ClassType

真的,这是真的

Python   2.5.1   ( r251 :54869,   Apr   18   2007,   22:08:04)
>>>   class   Something ( object ):
...       pass
...
>>>   Something
< class   '__main__.Something' >
>>>   type ( Something )
< type   'type' >

从这里可以看出在交互式解释器中创建的类是一个   first class  的对象。

类的类是……

它的元类……

就像对象是类的实例一样,类是它的元类的实例。

调用元类可以创建类。

确切来说, Python  中的其它对象也是如此。

因此当你创建一个类时……

解释器会调用元类来生成它……

定义一个继承自   object  的普通类意味着调用   type  来创建它:

>>> help(type)

Help on class type in module __builtin__:

 

class type(object)

 | type(object) -> the object's type

 | type(name, bases, dict) -> a new type

type  的第二种用法尤为重要。当   Python  解释器在执行一条类定义语句时(如例子中最初的两行代码之后),它会用下面的参数调用   type

  • 字符串形式的类名
  • 元组形式的基类序列——在我们的例子中是只有一个元素的元组( ’one-pl’ [1] ,如 (object,)
  • 包括由名字影射的类成员(类属性、方法等)的字典

简单模拟

>>>   def   __init__ ( self ):
...       self . message   =   'Hello World'
...
>>>   def   say_hello ( self ):
...       print   self . message
...
>>>   attrs   =   { '__init__' :   __init__ ,   'say_hello' :   say_hello }
>>>   bases   =   ( object ,)
>>>   Hello   =   type ( 'Hello' ,   bases ,   attrs )
>>>   Hello
< class   '__main__.Hello' >
>>>   h   =   Hello ()
>>>   h . say_hello ()
Hello   World

以上代码创建了类属性的字典,然后调用   type  来创建了名为   Hello  的类。

__metaclass__  的魔法

只要在类定义中把   __metaclass__  设置为任意有着与   type  相同参数的可调用对象,就能够提供自定义的元类。

通常使用从   type  继承的方法:

class   PointlessMetaclass ( type ):
    
def   __new__ ( meta ,   name ,   bases ,   attrs ):
        
# do stuff...
         return   type . __new__ ( meta ,   name ,   bases ,   attrs )

重要的是在   __new__  方法中我们能够读取或改变传入的用以创建新类的参数。从而能够内省属性字典和改动、增加或者删除成员。

尽管当实例化一个类时这两个函数都会被调用,但覆盖   __new__    __init__  更为重要。 __init__  初始化一个实例,而   __new__  的职责是创建它。因此如果元类用以自定义类的创建,就需要覆盖   type  __new__

使用新类而非仅仅提供工厂函数的原因在于如果使用工厂函数(那样只是调用   type )的话元类不会被继承。

In Action...

>>>   class   WhizzBang ( object ):
...       __metaclass__   =   PointlessMetaclass
...
>>>   WhizzBang
< class   '__main__.WhizzBang' >
>>>   type ( WhizzBang )
< class   '__main__.PointlessMetaClass' >

WhizzBang  是一个类,但它现在已经不是   type  的实例,而是我们自定义的元类的实例了……

这有什么用?

很好的问题,元类将用在创建使用了它的新类时调用,这里是一些关于这样做的好处的观点:

  • 装饰( Decorate )类的所有方法,用以日志记录或者性能剖分。
  • 自动   Mix-in  新方法
  • 在创建时注册类。(例如自动注册插件或从类成员创建数据库模式。)
  • 提供接口注册,功能自动发现和接口适配。
  • 类校验:防止子类化,校验所有的方法是否都有   docstrings

最重要之处在于元类中是在最后对   type  的调用时才真正创建类,所以可以自由地随你喜欢地改变属性字典(以及名称和元组形式的基类序列)。

一些流行的   Python ORM Object Relational Mappers (对象关系影射),用以和数据库协同工作)也如此使用元类。

哦,还有因为元类是继承的,所以你能够提供一个使用了你的元类的基类,而继承自它的子类就无需显式声明它了。

但是……

我曾未需要使用它来编写代码……(我们用它来剖分,也在   Ironclad   项目广泛应用它,但我不编写这些)。

还有,这一切只适用于   Python 2.x ,其中的机制在   Python 3  中已经改变了。

type(type) is type

  Python 2.6  中现在也可用使用  class decorators   来实现许多以前可能需要用元类来实现的东西。

最后,还有一个极尽奇技淫巧的例子(稍为深入,但仍然不难消化),可以去看看   The Selfless Metaclass 。它通过字节码和方法签名重写来避免显式地声明   self 

分享到:
评论

相关推荐

    深入理解python元类

    Python元类是编程语言中的一个高级特性,它允许我们对类的行为进行定制,甚至改变类的创建方式。元类在Python中扮演着一种"类的类"的角色,它定义了如何构建和操作常规的类。元类的强大之处在于,它们可以用于实现...

    Python的元类编程研究

    ### Python的元类编程研究 #### 概述 Python作为一种高级、通用的编程语言,以其简洁易读的语法和强大的功能赢得了广泛的认可。它不仅适用于Web开发、数据分析、人工智能等多个领域,同时也支持多种编程范式,包括...

    Python的元类编程研究.pdf

    根据提供的文件内容,以下是关于Python元类编程研究的知识点总结: 1. Python语言概述 Python是一种面向对象的解释性编程语言,具有高度的通用性,适用于多种操作系统平台。它以简洁清晰的语法特点著称,适合开发...

    Python语言特性.docx_python面试

    元类是创建类的类,Python 中的类是通过元类创建的。元类可以控制类的创建过程,并且可以在类创建时执行一些特殊的操作。 3. @staticmethod 和 @classmethod Python 中有三种方法:实例方法、类方法和静态方法。...

    Python 元类实例解析

    在Python中,所有类的类型都是元类type,即type是所有Python类的“母类”。 首先,需要了解Python中的基本概念——对象(Object)。在Python的世界里,一切皆对象,包括数字、字符串、列表、字典等。每个对象都有三...

    python中元类在创建类和实例的作用

    python中元类在创建类和实例的作用 最近在研究backtrader的底层源代码,作者用类若干的类和元类,以前没有接触过元类,现在经过查了一些资料,知道了元类是创建类的类,可以用来控制类的创建和实例的创建过程,也...

    第七章Python对象和类习题及答案--中文

    Python 对象和类习题及答案中文 在本节中,我们将学习 Python 中的对象和类,并通过习题和答案来巩固相关知识点。 定义对象的类 在 Python 中,类是定义对象的模板或蓝图。类是定义相同类型对象的模板,蓝图或...

    MQTT客户端(python封装的类)

    MQTT客户端(python封装的类),类的方法包括连接、订阅和发布。

    Python中的元类编程入门指引

    Python中的元类编程是一种高级特性,它涉及到对类这一概念的元层次操作。元类(Metaclass)可以理解为创建类的类,就像类是创建对象的模板一样。元类在Python中扮演着一个特殊的角色,它使得我们能够在类定义阶段...

    深入了解python中元类的相关知识

    在Python中,元类是一个非常高级的概念,它涉及到类的创建和对象模型的深层次机制。理解元类不仅可以帮助我们深入理解Python的面向对象机制,还可以在需要自定义类创建行为的时候提供强大的工具。下面我们将从几个...

    python C++包装类

    首先,我们需要理解什么是C++封装的Python类。这是一种技术手段,通过它,C++可以创建一个类,该类能够调用Python的函数、模块或者对象。这种封装通常利用Python的C API(Python的C语言接口)或者第三方库如Boost....

    两句话带你完全掌握Python最难知识点——元类!

    元类是Python编程中一个高级且复杂的概念,它在大多数初学者眼中可能显得有些晦涩难懂。然而,一旦理解了元类的工作原理,你就能更深入地掌握Python的精髓,甚至可以创建出更加灵活和定制化的类。下面,我们就通过两...

    从C++导出类到Python

    本教程将聚焦于如何从C++中导出类到Python,这样你就可以在Python环境中利用C++的强大性能和效率。这通常通过Python的C API或者第三方库如SWIG(Simplified Wrapper and Interface Generator)来实现。 **C++导出类...

    Python中类的定义结构以及类属性说明示例

    使用环境:需要先安装PyCharm(请自己百度下载安装),以及然后官网上下载Python 2.7版本,以及Python 3.7版本后,安装在自己的电脑上。...目的:帮助理解类对象和实例对象概念在Python中的具体使用。

    基于python对遥感影像的非监督分类

    基于python对遥感影像的非监督分类

    Python面向对象之类和对象实例详解

    本文实例讲述了Python面向对象之类和对象。分享给大家供大家参考,具体如下: 类和对象(1) 对象是什么? 对象=属性(静态)+方法(动态); 属性一般是一个个变量;方法是一个个函数; #类的属性 就是 类变量 #...

    基于python的类案检索demo源码.zip

    【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设...基于python的类案检索demo源码.zip基于python的类案检索demo源码.zip

    Python 元类使用说明

    霍霍》 定义一个元类(就所一个类的模板!莫多想,还要记住这是类级别的,不是对象级别的!): 复制代码 代码如下: class MyMeta(type): def __init__(cls,name,bases,dic): print cls.__name__ print name def __...

    python有限元分析框架-《有限元分析基础教程》(曾攀)笔记一-二维杆单元有限元程序(基 .pdf

    《有限元分析基础教程》(曾攀)笔记一主要探讨了如何使用Python构建二维杆单元的有限元程序,相比书中基于Matlab的实现,作者采用了更简洁和面向对象的编程方式。以下是关于这个主题的详细解释: 有限元分析是一种...

Global site tag (gtag.js) - Google Analytics