python - 弱引用类型的行为 - 无法理解

标签 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 只是替换伪装的属性)。甚至 isinstance 也将 y 标识为 set

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

最佳答案

x.__class__type(x) 不等价。 type(x) Root 于 typeobject.c , 并将返回真实类型 ob_type

/* Special case: type(x) should return x->ob_type */

虽然 x.__class__ 只是一个属性查找。它等效于 object.__getattribute__(x, '__class__'),除非属性查找已被重新定义。
object'__class__'是一个数据描述符,在typeobject.c中也有定义.它的getter也返回 ob_type。因此,在大多数情况下,x.__class__type(x) 返回相同的东西。

但是weakproxy,即_PyWeakref_ProxyType,故意定义了自己的proxy_getattr .这就是为什么 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)isinstance(c, C) 在这个例子中都是真的。因为 isinstance 会先检查 ob_type 是否相等。

关于python - 弱引用类型的行为 - 无法理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15624948/

相关文章:

python - 将每一行与数据框中的所有行进行比较,并将每行的结果保存在列表中

python - 如何在 Windows 上使用 iPython Notebook 解决 pandas 的导入错误?

python - 当我们通过索引访问列表中的元素时,CPython 会做什么?

python - 为什么Python的timeit()会无限执行?

python - 如何在 ipython 的命名空间中重新加载对象

python - 删除满足条件的子系列(数据框中的行)

python - 如何禁止在实例上调用类方法?

python - 在 init 中引发异常会导致 SystemError : returned a result with an error set in Python C API

python - CPython 是否实现了 PEP 380 中提到的优化?

Python从数据帧中提取行,其中数据位于另一个数据帧的两行之间