2017-11-07 8 views
1

getattrでオブジェクトの構成を実装し、オブジェクトを新しいプロセスに渡すと、getattrからRecursionErrorが返されます。次に例を示します。pythonオブジェクトの構成とマルチプロセッシング

from multiprocessing import Pool 

class Bar: 
    def __init__(self, bar): 
     self.bar = bar 

class Foo: 
    def __init__(self, bar): 
     self._bar = bar 

    def __getattr__(self, attr): 
     try: 
      return getattr(self._bar, attr) 
     except RecursionError: 
      print('RecursionError while trying to access {}'.format(attr)) 
      raise AttributeError 

def f(foo): 
    print(foo.bar) 

if __name__ == '__main__': 
    foo = Foo(Bar('baz')) 
    f(foo) 
    p = Pool(1) 
    p.map(f, [foo]) 

出力はこれです:

baz 
RecursionError while trying to access _bar 
baz 

なぜfooが_bar属性を見つけ、GETATTRに頼らなければならないのですか?

+0

これはなんですか? 'foo = Foo(Bar( 'baz'))'?それはあなたの意見で何をしますか? –

答えて

2

問題は、Pythonがfooオブジェクトをシリアル化し、新しいプロセスで復活させる必要があることです。 __init__は復活時に呼び出されないため、fooオブジェクトは._barという属性を早期に取得することはできません。

解決策は、特別にシリアル化/復活させる方法です。 __getattr__

def __getattr__(self, attr): 
    if attr in {'__getstate__', '__setstate__'}: 
     return object.__getattr__(self, attr) 
    return getattr(self._bar, attr) 

に変更してください。

関連する問題