的问题
询问如何在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
作为print语句
def __str__(self): return self.obj.__str__()
然后,
print b # prints out 1.22
现在我希望能够以与a相同的方式使用b进行算术运算,我认为这样做可以说我希望a
和b
的行为完全像{{{ 1}}。反正有没有这样做?我尝试添加诸如
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'
类以允许此操作有任何想法?
感谢您的任何建议!
答案 0 :(得分:3)
+
运算符是通过左操作数上的__add__()
方法或右操作数上的__radd__()
方法实现的。
答案 1 :(得分:0)
有两个潜在的问题。
首先,您似乎依赖于__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
while
中的__add__
循环确保您已将所有嵌套引用解压缩到基础对象。
如果我这样做,并且我使用类似的构造来实现代理模式,我会重构,以便while循环在它自己的方法中,比如getBaseObject(),然后在每次我们需要对象时调用这是参考链的实际基础。