7

次のサーバー コードを検討してください。

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__')

似たようなことをしましょうか?誰かが私に例を挙げて、これがどのように機能するかを説明してもらえますか?

アップデート

明確にするために:クラスを追加するとします:

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

ああ!!! これが正しい答えなのか、単なる回避策なのかわかりません...

4

1 に答える 1

0

確かに、反復可能であるためには、クラスが定義する__iter__メソッドを定義する必要がBaseProxyあるので、継承が正しい方法だと思います!

于 2011-05-17T10:50:01.280 に答える