【问题标题】:Simulating Pointers in Python for arithmetic在 Python 中模拟指针以进行算术运算
【发布时间】:2010-05-14 16:05:43
【问题描述】:

问题

Simulating Pointers in Python

询问如何在Python中模拟指针有一个很好的解决方案建议,即做

class ref:
    def __init__(self, obj): self.obj = obj
    def get(self): return self.obj
    def set(self, obj): self.obj = obj

然后可以用来做例如

a = ref(1.22)
b = ref(a)

print a # prints 1.22
print b.get() # prints 1.22

可以通过添加类来修改类以避免使用get作为打印语句

def __str__(self): return self.obj.__str__()

那么,

print b # prints out 1.22

现在我希望能够以与 a 相同的方式对 b 进行算术运算,我想这相当于说我希望 ab 的行为与 obj 完全相同。有没有办法做到这一点?我尝试添加诸如

之类的方法
def __getattribute__(self, attribute): return self.obj.__getattribute__(attribute)
def __call__(self): return self.obj.__call__()

但不管怎样,输出

print a + b

总是

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    print a + b
TypeError: unsupported operand type(s) for +: 'instance' and 'instance'

有人对如何修改ref 类以允许这样做有任何想法吗?

感谢您的建议!

【问题讨论】:

    标签: python pointers


    【解决方案1】:

    + 运算符通过左侧操作数的__add__() 方法或右侧操作数的__radd__() 方法实现。

    Here.

    【讨论】:

      【解决方案2】:

      有两个潜在的问题。

      首先,您似乎依靠您的__getattribute__ 实现来让解释器找到正确的__add__ 方法。不幸的是,我注意到 Python 解释器通常很难找到特殊函数,例如 __add____call__ 如果它们是动态创建的(也就是说,在定义类时没有明确地成为类的一部分)。手册明确承认这一点,至少对于新式类:

      对于新式类,隐式 特殊方法的调用是 只有在以下情况下才能保证正常工作 在对象的类型上定义,而不是在 对象的实例字典。

      尽管在我看来,即使使用旧式类,我也遇到过类似技巧的问题。

      其次,仅重定向 __add__ 是不够的。即使解释器成功还原

      a + b
      

      float.__add__( 1.22, b )
      

      float 类仍然不知道如何将float 添加到ref。因此,您的 __add__ 将不得不显式取消引用目标(如果它是间接引用,则取消引用(并取消引用......)像这样:

      class ref:
          def __init__(self, obj):
              self.obj = obj
          def get(self): return self.obj
          def set(self, obj): self.obj = obj
          def __str__(self): return self.obj.__str__()
          def __add__( self, other ):
              while isinstance( other, ref ):
                  other = other.obj
              return self.obj.__add__( other )
      
      a = ref(1.22)
      b = ref(a)
      
      print a
      print b
      
      print a + b
      

      __add__ 中的 while 循环确保您已将所有嵌套的 ref 解压到基础对象。

      如果我这样做,并且我使用了类似的构造来实现代理模式,我会重构,以便 while 循环在它自己的方法中,比如 getBaseObject(),然后在每次我们需要对象时调用那是参考链的实际基础。

      【讨论】:

        猜你喜欢
        • 2011-04-30
        • 1970-01-01
        • 2011-05-07
        • 2011-06-30
        • 2013-01-08
        • 1970-01-01
        • 2015-11-30
        • 2015-12-23
        • 2019-06-06
        相关资源
        最近更新 更多