2

如果我使用getattr实现对象组合并将对象传递到一个新进程,我会从getattr得到一个 RecursionError 。这是一个例子:

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

4

1 回答 1

3

问题是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)

它应该可以工作。

于 2017-11-07T18:24:34.500 回答