2015-10-28 22 views
0

我想讓一個pyro4代理索引。爲了驗證這一點,我把問候例如從http://pythonhosted.org/Pyro4/intro.html#simple-example,我修改了它:使pyro4代理索引

服務器:

import Pyro4 

class Test(object): 

    def __getitem__(self, index): 
     return index 

test = Test() 
print test[1] 
print test[100] 


daemon = Pyro4.Daemon() 
uri = daemon.register(test) 


print("Ready. Object uri =", uri) 
daemon.requestLoop() 

客戶:

import Pyro4 

uri = input("What is the Pyro uri of the object? ").strip() 

test = Pyro4.Proxy(uri) 
print test.__getitem__(1) 
print test.__getitem__(100) 

print test[1] 
print test[100] 

的[]符號的工作在服務器上,而不是還在客戶端代理上。我得到:

TypeError: 'Proxy' object does not support indexing

但直接調用__getitem__確實有效。

回答

1

我剛剛遇到了這個問題。

從我所看到的the source code中可以看出,Pyro4不會代理隱含的索引符號使用的Python __getitem__調用。它代理__getattr__,這就是爲什麼直接調用__getitem__方法的原因。

你能做什麼,不過,是創建(在客戶端)的代理火焰兵代理實現__getitem__,並讓所有其他方法調用告吹(!):

class TestProxy(object): 
    def __init__(self, pyroTest): 
     self.pyroTest = pyroTest 

    def __getattr__(self, name): 
     return getattr(self.pyroTest, name) 

    def __getitem__(self, item): 
     return self.pyroTest.__getitem__(item) 

然後你可以在TestProxy對象上使用索引符號,以及以普通Pyro方式調用方法。

(免責聲明:大概有各種各樣的Python的邊緣的情況下,這種簡單的解決方案不能覆蓋!)

這可能是值得火焰兵的增強請求。

+0

這確實有效。但是我在Pyro中看到了Python本身的問題。我期望[0]只是一個圍繞a._ getitem _(0)的句法加糖。相反,似乎有代碼檢查字典中是否存在_ getitem _。而這可能只是爲了讓錯誤消息fancier:object不可轉位,而不是_ getitem _未定義。 – andi

1

雖然這可能會被添加到Pyro代理中,但它實際上會促進潛在的可怕代碼。 索引一個對象通常是因爲對象是某種類型的集合,你可能正在迭代它。在Pyro代理上執行此操作會導致可怕的性能,因爲每個索引查找都將是遠程調用。 通常,使用一次遠程調用簡單地獲取想要一次迭代的集合,然後像往常一樣遍歷生成的本地對象,通常會更快,更高效。 YMMV,這取決於課程的情況。

+0

對於我最初想要這個功能的情況,我在列表中只有很少的項目。但我想要一個透明的鏡像在不同的過程中:更改代理會導致原始對象被更改。我放棄了,現在我發送一份副本並提供了API函數來更改列表。所以,儘管我現在使用你在這個答案中提出的建議,但另一個答案回答了我原來的問題。 – andi