Python 类型';weakref-can';我不明白

Python 类型';weakref-can';我不明白,python,cpython,Python,Cpython,我一直认为在Python解释器中,x的值与type(x)的值是等价的。但如果我们执行以下操作(在Python 2.7、3.3和PyPy2.0b1中): >>导入weakref >>>x=集合() >>>y=weakref.proxy(x) >>>x.uuu类uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu (,对) >>>y.。uuu类uuuuuuuuuuuuuuuuuuiInstance(y,集合),类型(y)

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

>>导入weakref
>>>x=集合()
>>>y=weakref.proxy(x)
>>>x.uuu类uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
(,对)
>>>y.。uuu类uuuuuuuuuuuuuuuuuuiInstance(y,集合),类型(y)
(,对)
我们将看到
y.\uuu class\uuuu
对应于
weakref.proxy
的包装类型(我假设
weakref.proxy
只是替换了伪装属性)。甚至
isinstance
也将
y
标识为
set


但是
type
显示“true”类型--
weakproxy
。所以,
type
没有使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?它是否为此使用了一些“更可靠”的来源?如果是这样,我们可以直接访问它吗?

x.\uuuu class\uuuu
type(x)
是不等价的。
type(x)
植根于,并将返回真正的类型
ob\u type

/*特殊情况:类型(x)应返回x->ob\U类型*/

x.\uuuuu class\uuuuu
只是一个属性查找。它相当于
对象。uuuu getattribute_uuuux,uuuu class_uuuu')
,除非重新定义了属性查找。
对象的
“类”
是一个数据描述符,也在中定义。它还返回
ob_type
。因此,在大多数情况下,
x.\uu类
类型(x)
返回相同的结果。

但是
weakproxy
,即
\u-PyWeakref\u-ProxyType
,故意定义了自己的。这就是为什么
y.\uu class\uu
与您案例中的
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'>
A类(对象):
通过
C类(对象):
def uu getattribute_uu(self,name):
如果名称='\uuuuu类\uuuuuu':
归还
返回对象。\uuuGetAttribute(self,name)
>>>c=c()
>>>c._类__
>>>类型(c)

此外,
isinstance(c,A)
isinstance(c,c)
在本例中都是正确的。因为
isinstance
将首先检查
ob\u type
的相等性。

谢谢您的回答。关于
isinstance
。它是否首先检查
ob\u type
,然后,如果它不等于,
\uuu class\uuuu
。实际上,它们之间有一个特殊的钩子。
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'>