具有装饰功能的多处理池给了我 "object has no attribute"
multiprocessing Pool with decorated function gives me "object has no attribute"
下面是一个可重现的代码:
from multiprocessing import Pool
def method_exception_catcher(method):
def method_exception_caught(*args, **kwargs):
try:
return method(*args, **kwargs)
except Exception as e:
raise type(e)(str(e) + ' from [{}] method'.format(method.__name__))
return method_exception_caught
class MyClass():
@method_exception_catcher
def do_something(self, elem):
return 1/0
@method_exception_catcher
def parallel_do_something(self):
with contextlib.closing(Pool(processes=1)) as p:
procs = [p.apply_async(self.do_something, args=(3, )) for k in range(1)]
results = [proc.get() for proc in procs]
p.close()
p.join()
return results
MyClass().parallel_do_something()
该代码给我 "AttributeError: 'MyClass' object has no attribute 'method_exception_caught'" 错误。
我该如何解决这个问题并让它成功地提高除以 0 的错误?谢谢!!
更新:
这是完整的错误输出:
Process ForkPoolWorker-4:
Traceback (most recent call last):
File "/usr/lib64/python3.6/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib64/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 108, in worker
task = get()
File "/usr/lib64/python3.6/multiprocessing/queues.py", line 337, in get
return _ForkingPickler.loads(res)
AttributeError: 'MyClass' object has no attribute 'method_exception_caught'
Pickling 一个函数只是写下它的(模块和)名称; unpickling(导入模块并)查找名称。因为你的 class 的方法( 即 ,从装饰器返回的函数)有一个 __name__
的 method_exception_caught
,这就是酸洗使用的。
答案(出于其他原因,这也是一个好主意)是使用 functools.wraps
让您的包装函数模拟包装函数:
def decorator(f):
@functools.wraps(f)
def wrap(*a,**kw): return f(*a,**kw)
return wrap
下面是一个可重现的代码:
from multiprocessing import Pool
def method_exception_catcher(method):
def method_exception_caught(*args, **kwargs):
try:
return method(*args, **kwargs)
except Exception as e:
raise type(e)(str(e) + ' from [{}] method'.format(method.__name__))
return method_exception_caught
class MyClass():
@method_exception_catcher
def do_something(self, elem):
return 1/0
@method_exception_catcher
def parallel_do_something(self):
with contextlib.closing(Pool(processes=1)) as p:
procs = [p.apply_async(self.do_something, args=(3, )) for k in range(1)]
results = [proc.get() for proc in procs]
p.close()
p.join()
return results
MyClass().parallel_do_something()
该代码给我 "AttributeError: 'MyClass' object has no attribute 'method_exception_caught'" 错误。
我该如何解决这个问题并让它成功地提高除以 0 的错误?谢谢!!
更新:
这是完整的错误输出:
Process ForkPoolWorker-4:
Traceback (most recent call last):
File "/usr/lib64/python3.6/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib64/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib64/python3.6/multiprocessing/pool.py", line 108, in worker
task = get()
File "/usr/lib64/python3.6/multiprocessing/queues.py", line 337, in get
return _ForkingPickler.loads(res)
AttributeError: 'MyClass' object has no attribute 'method_exception_caught'
Pickling 一个函数只是写下它的(模块和)名称; unpickling(导入模块并)查找名称。因为你的 class 的方法( 即 ,从装饰器返回的函数)有一个 __name__
的 method_exception_caught
,这就是酸洗使用的。
答案(出于其他原因,这也是一个好主意)是使用 functools.wraps
让您的包装函数模拟包装函数:
def decorator(f):
@functools.wraps(f)
def wrap(*a,**kw): return f(*a,**kw)
return wrap