Python __class__()
Python __class__()
在 Python 的文档中 __class__
被描述为一个属性。在对象 type
(元类)中,__class__
似乎是一个方法。
如果我们这样做:
>>> class Foo:
pass
>>> a = Foo()
>>> a.__class__ == type.__class__(a)
True
所以,我的问题是:
- 当我们调用
a.__class__
时,我们真的调用了方法type.__class__(a)
吗?
- 这就是为什么
__class__
不是 a
的 __dict__
属性成员的原因吗?
__class__
是一个 data descriptor object。 Python 核心对象的许多属性都作为描述符实现。您应该将其视为实现细节,仅此而已。
__class__
是一个描述符,因为 Python 需要能够验证您分配给它的新值;分配给 __class__
需要遵守某些限制,而将 __class__
设为描述符是最有效的方法。
当您尝试访问对象的属性时,会自动找到描述符对象并在类型上调用。 instance.__class__
将在 class 上找到并执行 __class__
描述符(通过搜索继承图中的所有 classes),通常以 object.__dict__['__class__'].__get__(instance, type(instance))
(其中 object
通常是 type(instance).__mro__
序列中找到 __class__
属性的第一个 class);发生这种情况是因为 Python 将始终使用类型的 __getattribute__
方法来查找属性,并且该方法知道如何处理在 class 和基类上找到的描述符,以及查看 object.__dict__
属性。所以它们不依赖于对象 __dict__
本身,它们依赖于对象类型,这是设计的。
现在,class 对象也是 可调用 对象。这就是创建实例的方式;对于给定的 class Foo
,您可以通过调用它来创建一个实例,因此 Foo()
。 instance.__class__
只是对 class 对象的引用,就像 class_obj = Foo
会创建对 class 的引用一样。调用 class 对象会产生一个新实例,无论您使用什么引用来访问它。
最后,type.__class__
只是对 type()
本身的引用:
>>> type.__class__ is type
True
>>> type.__class__
<class 'type'>
>>> type(type)
<class 'type'>
那是因为 type
是它自己的类型。 Python 类型系统的父子关系必须在某个地方停止,而 type
就是那个点。
在您的示例中,a.__class__
是对 Foo
class 的引用。 type.__class__
与 type
是同一个对象,所以你实际上是这样做的:
Foo == type(a)
确实如此,a
的类型是Foo
。
在 Python 的文档中 __class__
被描述为一个属性。在对象 type
(元类)中,__class__
似乎是一个方法。
如果我们这样做:
>>> class Foo:
pass
>>> a = Foo()
>>> a.__class__ == type.__class__(a)
True
所以,我的问题是:
- 当我们调用
a.__class__
时,我们真的调用了方法type.__class__(a)
吗? - 这就是为什么
__class__
不是a
的__dict__
属性成员的原因吗?
__class__
是一个 data descriptor object。 Python 核心对象的许多属性都作为描述符实现。您应该将其视为实现细节,仅此而已。
__class__
是一个描述符,因为 Python 需要能够验证您分配给它的新值;分配给 __class__
需要遵守某些限制,而将 __class__
设为描述符是最有效的方法。
当您尝试访问对象的属性时,会自动找到描述符对象并在类型上调用。 instance.__class__
将在 class 上找到并执行 __class__
描述符(通过搜索继承图中的所有 classes),通常以 object.__dict__['__class__'].__get__(instance, type(instance))
(其中 object
通常是 type(instance).__mro__
序列中找到 __class__
属性的第一个 class);发生这种情况是因为 Python 将始终使用类型的 __getattribute__
方法来查找属性,并且该方法知道如何处理在 class 和基类上找到的描述符,以及查看 object.__dict__
属性。所以它们不依赖于对象 __dict__
本身,它们依赖于对象类型,这是设计的。
现在,class 对象也是 可调用 对象。这就是创建实例的方式;对于给定的 class Foo
,您可以通过调用它来创建一个实例,因此 Foo()
。 instance.__class__
只是对 class 对象的引用,就像 class_obj = Foo
会创建对 class 的引用一样。调用 class 对象会产生一个新实例,无论您使用什么引用来访问它。
最后,type.__class__
只是对 type()
本身的引用:
>>> type.__class__ is type
True
>>> type.__class__
<class 'type'>
>>> type(type)
<class 'type'>
那是因为 type
是它自己的类型。 Python 类型系统的父子关系必须在某个地方停止,而 type
就是那个点。
在您的示例中,a.__class__
是对 Foo
class 的引用。 type.__class__
与 type
是同一个对象,所以你实际上是这样做的:
Foo == type(a)
确实如此,a
的类型是Foo
。