如果我使用 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?
最佳答案
问题是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)
它应该可以工作。
关于python 对象组合和多处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47164697/