为什么MyClass .__ class__返回的值不同于MyClass().__ class__?

时间:2011-06-04 14:39:21

标签: python inheritance reflection multiple-inheritance method-resolution-order

我希望能够调用'person.Person。 class '并取回'class person.Person',就像它对一个人对象一样:

>>> p = person.Person()
>>> p.__class__
<class 'person.Person'>
>>> person.Person.__class__
<class 'perframe.datatype.TypeSystemMeta'>

这是Person继承树......

class TypeSystem(object):
    __metaclass__ = TypeSystemMeta    

class Model(TypeSystem):
    pass    

class Node(Vertex,Model):
    pass

class Person(Node):
    pass

这里发生了什么?

3 个答案:

答案 0 :(得分:5)

在Python中,即使是类也是对象,每个对象都是类的实例。 Person指的是“类对象”,它是type的一个实例。在这种情况下,游戏中有一个元类 - 高度混乱的元编程魔术,但如果你想要一个介绍,请参阅What is a metaclass in Python?。如果你声明一个class Foo(object)Foo.__class__ is type(对于不从对象继承的旧式classe,事情会有所不同,更加混乱)。顺便说一下,这导致更加奇怪的是type似乎是它自己的一个实例。

答案 1 :(得分:2)

只需使用对person.Person的引用:

>>> p = person.Person() 
>>> p.__class__ 
<class 'person.Person'> 
>>> person.Person
<class 'person.Person'> 

Python类型系统的一个非常有用的资源是版本2.2 +的Python类型系统的原始草案。

http://www.python.org/download/releases/2.2/descrintro/

答案 2 :(得分:1)

要了解为什么要获得所做的结果,您必须了解元类是什么。要理解这一点,您必须了解如何在Python中创建类。

当您编写class语句时,解释器会打开一个新的命名空间,执行语句中的代码,并在该代码运行后查看命名空间的状态。然后计算出重要的细节(局部变量,类的名称,......)并将其传递给内置类type。因此type的实例通常称为类,因此type是“元类”。

当您覆盖元类时,您告诉Python不要使用type来创建新类。相反,它会将相同的东西传递给自定义类。这允许您覆盖type中的默认值。

因此,person.Person是通过将一些参数传递给元类来创建的。特别是,它是该类的一个实例,因此它的__class__是元类!