Python中的元类(译)

add by zhj: 这是大stackoverflow上一位小白提出的问题,好吧,我承认我也是小白,元类这块我也是好多次想搞明白,

但终究因为太难懂而败下阵来。看了这篇文章明白了许多,再加下啄木鸟社区的 Python 类型和对象  这篇文章。卧槽,

这简直就是珠联璧合,日月神剑啊,尼玛。终于干掉了元类。翻译时有修改,建议与原文一起看。

原文:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python?answertab=votes#tab-top

类是对象

在理解元类之前,你需要先掌握Python中的类。在Python中,对类的定义比较特殊,这点借鉴了Smalltalk语言。在大多

数语言中,类只是用于描述如何创建对象的代码片,在Python中,在一定程度上也是这样:

>>> class ObjectCreator(object):
...       pass
... 

>>> my_object = ObjectCreator()
>>> print(my_object)
<__main__.ObjectCreator object at 0x8974f2c>

不过,Python中的类不止如此。类也是对象,是的,我没说错。

当你使用关键字class时,Python解释器执行时,会创建一个对象。如下,Python会在内存中创建一个对象,并在符号表

中增加一个标识符ObjectCreator,指向那个对象,这就是Python中所说的引用,我们也常称之为变量。

>>> class ObjectCreator(object):
...       pass
... 

我们称这个对象为类对象,因为该对象可以实例化,创建实例对象,因此我们称它为类。

因为它是一个对象,所以:

  • 可以将它赋给一个变量
  • 可以copy它
  • 可以给它增加属性
  • 可以将它作为函数参数

比如

>>> print(ObjectCreator) # 可以print it
<class ‘__main__.ObjectCreator‘>
>>> def echo(o):
...       print(o)
...
>>> echo(ObjectCreator) # 类对象作为函数参数
<class ‘__main__.ObjectCreator‘>
>>> print(hasattr(ObjectCreator, ‘new_attribute‘))
False
>>> ObjectCreator.new_attribute = ‘foo‘ # 增加类的属性
>>> print(hasattr(ObjectCreator, ‘new_attribute‘))
True
>>> print(ObjectCreator.new_attribute)
foo
>>> ObjectCreatorMirror = ObjectCreator # 赋值给另一个变量
>>> print(ObjectCreatorMirror.new_attribute)
foo
>>> print(ObjectCreatorMirror())
<__main__.ObjectCreator object at 0x8997b4c>

通过type类动态创建类

其实,类对象也是实例化的结果,即类对象是由另一个类实例化得到的,我们称该类为元类,即元类是产生类的类,反之也成立,

如果类X实例化后得到是类对象,那X就是元类。在Python中,只有type类及其子类才可以当元类。多说一句,这里会有鸡生蛋、

蛋生鸡的问题。在Python中,一切都是对象,一切对象都是类实例化的结果。对象由类实例化得到,而类也是对象,它也是由类(元类)

实例化得到,继续向上,元类也是对象,也要由另一个元类实例化得到,这样下去就没有尽头了。在Python中,这个追溯终止在type类。

元类是type类或其子类,而type类的元类就是它自己,哈哈,type类自己创建自己,牛逼吧,当然type类的这个特性是Python设计者

guido van rossum等人设计并实现的。至于Python解释器是怎么找到元类的,后面我们会讲。

还记得type()方法吗?我们常用它看一个对象X所属的类,即创建该对象X的类,当对象X是类对象时,看到的就是元类。如下,

>>> print(type(1))
<type ‘int‘>
>>> print(type("1"))
<type ‘str‘>
>>> print(type(ObjectCreator))     #查看创建ObjectCreator类的类
<type ‘type‘>
>>> print(type(ObjectCreator()))
<class ‘__main__.ObjectCreator‘>

type类还有另外一个功能,它可以创建类,将类的一些信息做为type()的参数,并返回一个类。我知道,type根据输入参数的不同而有不同的功能,

这种做法是愚蠢的。当type()只有一个参数时,它的功能就是返回创建该参数对象的类;当多于一个参数时,type()才是type类的实例化,实例化得到

一个类并返回该类。type创建类时,参数格式如下,classname是类名,字符串类型,parentclasses是类所有父类,元组类型,attrs是类的所有{属性:值},

字典类型。

type(classname, parentclasses , attrs)

比如,

>>> class MyShinyClass(object):
...       pass

当解释器执行时,会转为下面的语句,当然,你也可以直接这么写。

MyShinyClass = type(‘MyShinyClass‘, (object,), {})

下面我们来定义一个类,并在类中定义属性,如

>>> class Foo(object):
...       bar = True

它会被翻译成下面的形式,

>>> Foo = type(‘Foo‘, (), {‘bar‘:True})

用用看吧

>>> print(Foo)
<class ‘__main__.Foo‘>
>>> print(Foo.bar)
True
>>> f = Foo()
>>> print(f)
<__main__.Foo object at 0x8a9b84c>
>>> print(f.bar)
True

我们可以用另一个类继承它,so:

>>>   class FooChild(Foo):
...         pass

would be:

>>> FooChild = type(‘FooChild‘, (Foo,), {})
>>> print(FooChild)
<class ‘__main__.FooChild‘>
>>> print(FooChild.bar) # bar is inherited from Foo
True

OK,你会想给你的类增加方法。定义一个函数,并将它分配给类的属性

>>> def echo_bar(self):
...       print(self.bar)
...
>>> FooChild = type(‘FooChild‘, (Foo,), {‘echo_bar‘: echo_bar})
>>> hasattr(Foo, ‘echo_bar‘)
False
>>> hasattr(FooChild, ‘echo_bar‘)
True
>>> my_foo = FooChild()
>>> my_foo.echo_bar()
True

说到这里,你应该已经明白了类的创建过程。那Python创建类都是这么简单吗?都是直接用type元类实例化得到?

不是的,你可以指定元类,这就是__metaclass__属性。

什么是元类

元类就是创建类的类(话说作者说话够罗嗦的,当然,对于小白来说,多说几次才能看明白)

在上面,我们提到可以使用type()查看创建一个对象的类,你也可以使用__class__,如下

>>> age = 35
>>> age.__class__
<type ‘int‘>
>>> name = ‘bob‘
>>> name.__class__
<type ‘str‘>
>>> def foo(): pass
>>> foo.__class__
<type ‘function‘>
>>> class Bar(object): pass
>>> b = Bar()
>>> b.__class__
<class ‘__main__.Bar‘>

那__class__.__class__是什么呢?__class__返回的是一个类对象,再一次__class__返回的就是元类,如下

,下面这个结论并不具备普适性,有些类的元类并非元类。当然,如果你一直调用__class__,在有限次之后,

它返回的就一直是type类了。

>>> age.__class__.__class__
<type ‘type‘>
>>> name.__class__.__class__
<type ‘type‘>
>>> foo.__class__.__class__
<type ‘type‘>
>>> b.__class__.__class__
<type ‘type‘>

什么是元类

时间: 2024-10-10 08:23:24

Python中的元类(译)的相关文章

Python中的元类(metaclass)

推荐+收藏:深刻理解Python中的元类(metaclass) 做一些笔记学习学习: 在大多数编程语言中,类就是用来描述如何生成一个对象的代码段,在Python中类也是一个对象,这个(类)对象自身拥有创建对象(类实例)的能力. 因为它的本质是一个对象: 可以将它赋值给一个变量 可以拷贝它 增加属性 作为参数进行传递 可以在运行时动态地创建他们,可以在函数中创建类,只需要使用class关键字即可 当使用class关键字的时候,Python解释器会自动地创建这个对象,Python还提供了手动处理的方

深刻理解Python中的元类

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

深刻理解Python中的元类(metaclass)以及元类实现单例模式

深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对python的面向对象有了更加深入的了解.这里将一篇写的非常好的文章基本照搬过来吧,这是一篇在Stack overflow上很热的帖子,我看http://blog.jobbole.com/21351/这篇博客对其进行了翻译. 一.理解

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

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

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

本文由 伯乐在线 - bigship 翻译 英文出处:stackoverflow 译文:http://blog.jobbole.com/21351/ 译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程.于是e-satis同学给出了神一般的回复,该回复获得了9

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

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

Python中的元类

从前面"Python对象"文章中了解到,在Python中一切都是对象,类可以创建实例对象,但是类本身也是对象. class C(object): pass c = C() print c.__class__ print C.__class__ 代码中,通过"__class__"属性来查看对象的类型,对于类C对象本身,它的类型是type. 由于类也是对象,所以就可以在运行时动态的创建类,那么这时候就要用到内建函数type了. 再看type 从前面的文章了解到,可以通过

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

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

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

注:本文原稿来自stackoverflow,原文链接,目前已收获5k高赞. 一.类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Python中这一点仍然成立: >>> class ObjectCreator(object): … pass … >>> my_object = ObjectCreator() >>>