【问题标题】:Where to find __repr__ of Python weakref proxy?在哪里可以找到 Python 弱引用代理的 __repr__?
【发布时间】:2021-02-06 08:39:56
【问题描述】:

我现在有点困惑:

import weakref

class A:
    def __init__(self, p):
        self.p = p
        
    def __repr__(self):
        return f"{type(self).__name__}(p={self.p!r})"
    
a = A(1)
proxy_a = weakref.proxy(a)

print(repr(proxy_a))
# '<weakproxy at 0x7f2ea2fc1b80 to A at 0x7f2ea2fee610>'
print(proxy_a.__repr__())
# 'A(p=1)'

为什么repr(proxy_a) 返回代理的表示,而proxy_a.__repr__() 返回原始对象的表示?这两个电话不应该归结为同一件事吗?而使用repr(proxy_a)实际调用的是哪个__repr__实现?

【问题讨论】:

    标签: python weak-references repr


    【解决方案1】:

    repr(proxy_a)weakref.proxy 对象调用repr 的默认C 实现。而proxy_a.__repr__() 代理来自a 对象的版本。

    是的,我希望它们执行相同的代码,但是等等,我们不希望代理也向代理对象发送属性查找和方法调用吗?同时我希望看到代理是代理对象,所以repr(proxy_a) 结果也很有意义。所以甚至不清楚什么应该是正确的行为。

    这方面的信息非常稀少,但看起来weakref.proxy 对象并没有以完全透明的方式替换原始对象,这与普遍预​​期相反。

    添加了一些打印行以使事情更清晰。请注意,在最后一行中,可以通过代理绑定方法的__self__ 参数访问弱引用对象及其方法。

    import weakref
    
    class A:
        def __init__(self, p):
            self.__p = p
            
        def __repr__(self):
            return f"{type(self).__name__}(p={self.__p!r})"
    
    a = A(1)
    proxy_a = weakref.proxy(a)
    
    print(repr(proxy_a))
    # '<weakproxy at 0x7f2ea2fc1b80 to A at 0x7f2ea2fee610>'
    print(proxy_a.__repr__())
    # 'A(p=1)'
    print(proxy_a.__repr__)
    # <bound method A.__repr__ of A(p=1)>
    print(type(proxy_a))
    # <class 'weakproxy'>
    print(type(proxy_a.__repr__.__self__))
    # <class '__main__.A'>
    print(proxy_a.__repr__.__self__.__repr__())
    # A(p=1)
    

    另请参阅此完整线程 python-dereferencing-weakproxy 以及来自 Python bugtracker 的此(旧)thread 中的一些条目,其中在多个地方提到了 weakref.proxy 和方法委托。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多