2015-10-28 4 views
0

Я пытаюсь сделать прокси-сервер pyro4 индексируемым. Чтобы проверить это, я взял приветствие пример из http://pythonhosted.org/Pyro4/intro.html#simple-example, и я изменил его:make pyro4 proxy indexable

Сервер:

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__ do work.

ответ

1

Я просто наткнулся на это сам.

Из того, что я вижу, глядя на the source code, Pyro4 не проксирует неявный Python __getitem__, который использует эту нотацию индекса. Он делает прокси __getattr__, поэтому напрямую работает метод __getitem__.

Что вы можете сделать, хотя, это создать (на стороне клиента) прокси к прокси-серверу Pyro, который реализует __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.

(Отказ от ответственности: есть, вероятно, все виды вещие крайних случаев, что это простое решение не покрывает!)

Это может быть стоит просить повышения для Пиро.

+0

Это действительно работает. Но я вижу проблему больше в Python, а затем в Pyro. Я ожидал бы, что [0] будет просто синтаксическим сахаром вокруг a._ getitem _ (0). Вместо этого существует код, который проверяет наличие _ getitem _ в словаре. И это, возможно, просто для того, чтобы сделать сообщение об ошибке fancier: объект не индексируемый вместо _ getitem _ не определен. – andi

1

Хотя это может быть добавлено к прокси-серверу Pyro, оно фактически способствует потенциально ужасному исполняемому коду. Индексирование объекта обычно выполняется, потому что объект представляет собой некоторую коллекцию, и вы, вероятно, итерации по ней. Выполнение этого на прокси-сервере Pyro приведет к ужасной производительности, потому что каждый поиск индекса будет удаленным вызовом. Как правило, намного быстрее и эффективнее просто получить коллекцию, которую вы хотите перебирать по всему, используя один удаленный вызов, а затем перебирать результирующий локальный объект, как обычно. YMMV, это зависит от ситуации.

+0

Для случая, когда я изначально хотел эту функцию, у меня очень мало элементов в списке. Но я хотел, чтобы прозрачное зеркало в другом процессе: изменение прокси приведет к изменению исходного объекта. Я сдался, и теперь я отправляю копию и предлагаю функции API для изменения списка. Поэтому, хотя я использую теперь то, что вы предлагаете в этом ответе, другой ответ отвечает на мой первоначальный вопрос. – andi

 Смежные вопросы

  • Нет связанных вопросов^_^