类型与weakref的行为 - 无法理解

时间:2013-03-25 21:17:51

标签: python cpython

我一直认为在Python中,x.__class__type(x)的解释器值是等价的。但是如果我们执行以下操作(在Python 2.7,3.3和PyPy 2.0b1中):

>>> import weakref
>>> x = set()
>>> y = weakref.proxy(x)
>>> x.__class__, isinstance(x, set), type(x)
(<type 'set'>, True, <type 'set'>)
>>> y.__class__, isinstance(y, set), type(y)
(<type 'set'>, True, <type 'weakproxy'>)

我们会看到y.__class__对应weakref.proxy的包装类型(我想weakref.proxy只是替换了伪装的属性)。即使isinstancey标识为set

type显示“真实”类型 - weakproxy。因此,type不使用__class__属性来标识参数的类型,是吗?它是否为此目的使用了一些“更可靠”的来源?如果是这样,我们可以直接访问吗?

1 个答案:

答案 0 :(得分:4)

x.__class__type(x)不相同。 type(x)根植于typeobject.c,并会返回真实类型ob_type

  

/ *特殊情况:类型(x)应返回x-&gt; ob_type * /

虽然x.__class__只是一个属性查找。它等同于object.__getattribute__(x, '__class__'),除非重新定义了属性查找 object的{​​{1}}是一个数据描述符,也在typeobject.c中定义。其getter也会返回'__class__'。因此,在大多数情况下,ob_typex.__class__会返回相同的内容。

但是type(x),即weakproxy,故意定义了自己的proxy_getattr。这就是为什么_PyWeakref_ProxyType与您的y.__class__不同的原因。

在以下实验中,我们可以达到同样的效果。

type(y)

此外,class A(object): pass class C(object): def __getattribute__(self, name): if name == '__class__': return A return object.__getattribute__(self, name) >>> c = C() >>> c.__class__ <class '__main__.A'> >>> type(c) <class '__main__.C'> isinstance(c, A)在此示例中均为true。由于isinstance(c, C)会首先检查isinstance的相等性。