TypeError: объект AutoProxy не повторяется - многопроцессорная обработка - PullRequest
4 голосов
/ 17 мая 2011

рассмотрим следующий код сервера:

from multiprocessing.managers import BaseManager, BaseProxy

def baz(aa) :
    print "aaa"
    l = []
    for i in range(3) :
      l.append(aa)
    return l

class SolverManager(BaseManager): pass

manager = SolverManager(address=('127.0.0.1', 50000), authkey='mpm')
manager.register('solver', baz)

server = manager.get_server()
server.serve_forever()

и связанный с ним клиент:

import sys
from multiprocessing.managers import BaseManager, BaseProxy

class SolverManager(BaseManager): pass

def main(args) :
    SolverManager.register('solver')
    m = SolverManager(address=('127.0.0.1', 50000), authkey='mpm')
    m.connect()

    for i in m.solver(args[1]):
        print i

if __name__ == '__main__':
    sys.exit(main(sys.argv))

Я думаю, что здесь упущено что-то важное.Я предполагаю, что мне нужно создать подкласс класса BaseProxy для обеспечения итеративного объекта, но до сих пор мне не удалось получить его правильно.

когда я запускаю клиент, я получаю эту ошибку:

Traceback (most recent call last):
  File "mpmproxy.py", line 17, in <module>
    sys.exit(main(sys.argv))
  File "mpmproxy.py", line 13, in main
    for i in m.solver(args[1]):
TypeError: 'AutoProxy[solver]' object is not iterable

однако, если я пытаюсь распечатать его, список есть ... Может быть, это также связано с тем, как данные сериализуются между клиентом и сервером ...

в документации тамЭто аналогичный случай (с генератором), и они используют следующий класс для доступа к данным:

class GeneratorProxy(BaseProxy):
    _exposed_ = ('next', '__next__')
    def __iter__(self):
        return self
    def next(self):
        return self._callmethod('next')
    def __next__(self):
        return self._callmethod('__next__')

Должен ли я сделать что-то подобное?Кто-нибудь может дать мне пример и объяснить, как это работает?

update

Чтобы уточнить: предположим, я добавляю класс:

class IteratorProxy(BaseProxy):
    def __iter__(self):
        print self
        return self

и в клиенте я регистрирую функцию как

SolverManager.register('solver', proxytype=IteratorProxy)

ошибка, которую я получаю:

$python mpmproxy.py test
['test', 'test', 'test']
Traceback (most recent call last):
  File "mpmproxy.py", line 22, in <module>
    sys.exit(main(sys.argv))
  File "mpmproxy.py", line 18, in main
    for i in m.solver(args[1]):
TypeError: iter() returned non-iterator of type 'IteratorProxy'

У меня такое впечатление, что я упускаю что-то глупое здесь ...

обновление 2

Я думаю, что решил эту проблему:

Смысл состоял в том, чтобы получить реальное значение:

for i in m.solver(args[1])._getvalue():
    print i

Гоша!!!Я не уверен, что это правильный ответ или просто обходной путь ...

1 Ответ

0 голосов
/ 17 мая 2011

Действительно, чтобы быть повторяемым, ваш класс должен определить метод __iter__, который определяет BaseProxy, поэтому я думаю, что наследование - правильный путь!

...