2010-05-14 54 views
4

問題在在Python模擬指針算術

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 

類可以修改通過添加

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

然後,

print b # prints out 1.22 

現在我想能夠做算術,以避免使用get的打印語句與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類的任何想法允許這個?

感謝您的任何建議!

回答

3

+運算符通過左操作數的__add__()方法或右操作數的__radd__()方法實現。

Here

0

有兩個潛在的問題。

首先,你似乎是依靠你的__getattribute__實現來讓解釋器找到正確的__add__方法。不幸的是,我注意到Python解釋器在找到特殊函數時常常遇到問題,如__add____call__(如果它們是在動態創建的時候的話),也就是說,當類被定義時,它不是類的明確部分。該手冊明確地承認這一點,至少對新樣式類:

對於新樣式類,特殊的方法隱含 調用都 只能保證正常工作,如果在 一個對象的類型定義 ,不對象的實例字典。

雖然在我看來,即使使用舊式課程,我也遇到類似的技巧問題。

二,只是重定向__add__是不夠的。即使解釋成功降低

a + b 

float.__add__(1.22, b) 

浮動類仍然不知道如何將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() ),然後在每次我們需要在參考鏈的實際基礎上的對象時被調用。