python3 如何找出 apply_async 目标函数中的哪一行在应用 error_callback 时导致错误
python3 how to find out which line in apply_async target function caused error when error_callback is applied
使用 python 3.4
我有一个失败的目标函数,apply_async 调用我的错误回调函数而不是我的回调函数。
问题是捕获并发送到 error_callback 的异常没有帮助,我无法弄清楚 目标函数中的错误发生在哪里。
我的错误回调
def error_callback(self,e):
print('error_callback()',e)
# tested one of these at a time
traceback.print_exc()
traceback.print_last()
traceback.print_stack()
回溯输出
print_exc
File "/usr/lib/python3.4/traceback.py", line 125, in _iter_chain
context = exc.__context__
AttributeError: 'NoneType' object has no attribute '__context__'
print_last
File "/usr/lib/python3.4/traceback.py", line 262, in print_last
raise ValueError("no last exception")
ValueError: no last exception
print_stack
File "./relative/path/to/my/script.py", line 71, in traceback
traceback.print_stack()
我不得不承认,我对 traceback 库及其使用方法不是很满意,但在我看来,在这种情况下不可能使用 traceback?
我该怎么办?
您正在调用的 traceback
函数都期望从 sys.exec_info
获取异常信息,这是在捕获异常时通常存储异常信息的地方。但是,由于您的实际异常来自子进程,因此当您在父进程中调用它们时,它们找不到任何异常信息。
您需要使用从子进程收到的异常对象 e
中提取相关信息。尝试使用 traceback.print_exception
和适当的参数:
traceback.print_exception(type(e), e, e.__traceback__)
I can't figure out where the error in the target function occurs.
这是您可以执行的操作的示例:
import multiprocessing as mp
def do_stuff(num):
if False:
x = 10
else:
x = 20
result = 5/(2 - num) #Line 9
return result
def success_handler(result):
print('success')
def error_handler(e):
print('error')
print(dir(e), "\n")
print("-->{}<--".format(e.__cause__))
with mp.Pool(2) as my_pool:
results = [
my_pool.apply_async(
do_stuff,
args=(i,),
callback=success_handler,
error_callback=error_handler
)
for i in range(3)
]
try:
for result_obj in results:
print("result is: {}".format(result_obj.get()))
except ZeroDivisionError as e:
print("Oh, boy. This is the second time I've seen this error.")
--output:--
success
success
result is: 2.5
result is: 5.0
error
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback']
-->
"""
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "1.py", line 10, in do_stuff
result = 5/(2 - num) #Line 9
ZeroDivisionError: division by zero
"""<--
Oh, boy. This is the second time I've seen this error.
记下错误消息中目标函数的行号。
我不太明白 error_callback
的用途,因为在调用 error_callback 之后,多处理重新引发错误,所以无论如何你都必须捕获它。我想 error_calback 必须用于执行特定于进程的清理。
使用 python 3.4
我有一个失败的目标函数,apply_async 调用我的错误回调函数而不是我的回调函数。
问题是捕获并发送到 error_callback 的异常没有帮助,我无法弄清楚 目标函数中的错误发生在哪里。
我的错误回调
def error_callback(self,e):
print('error_callback()',e)
# tested one of these at a time
traceback.print_exc()
traceback.print_last()
traceback.print_stack()
回溯输出
print_exc
File "/usr/lib/python3.4/traceback.py", line 125, in _iter_chain
context = exc.__context__
AttributeError: 'NoneType' object has no attribute '__context__'
print_last
File "/usr/lib/python3.4/traceback.py", line 262, in print_last
raise ValueError("no last exception")
ValueError: no last exception
print_stack
File "./relative/path/to/my/script.py", line 71, in traceback
traceback.print_stack()
我不得不承认,我对 traceback 库及其使用方法不是很满意,但在我看来,在这种情况下不可能使用 traceback?
我该怎么办?
您正在调用的 traceback
函数都期望从 sys.exec_info
获取异常信息,这是在捕获异常时通常存储异常信息的地方。但是,由于您的实际异常来自子进程,因此当您在父进程中调用它们时,它们找不到任何异常信息。
您需要使用从子进程收到的异常对象 e
中提取相关信息。尝试使用 traceback.print_exception
和适当的参数:
traceback.print_exception(type(e), e, e.__traceback__)
I can't figure out where the error in the target function occurs.
这是您可以执行的操作的示例:
import multiprocessing as mp
def do_stuff(num):
if False:
x = 10
else:
x = 20
result = 5/(2 - num) #Line 9
return result
def success_handler(result):
print('success')
def error_handler(e):
print('error')
print(dir(e), "\n")
print("-->{}<--".format(e.__cause__))
with mp.Pool(2) as my_pool:
results = [
my_pool.apply_async(
do_stuff,
args=(i,),
callback=success_handler,
error_callback=error_handler
)
for i in range(3)
]
try:
for result_obj in results:
print("result is: {}".format(result_obj.get()))
except ZeroDivisionError as e:
print("Oh, boy. This is the second time I've seen this error.")
--output:--
success
success
result is: 2.5
result is: 5.0
error
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback']
-->
"""
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "1.py", line 10, in do_stuff
result = 5/(2 - num) #Line 9
ZeroDivisionError: division by zero
"""<--
Oh, boy. This is the second time I've seen this error.
记下错误消息中目标函数的行号。
我不太明白 error_callback
的用途,因为在调用 error_callback 之后,多处理重新引发错误,所以无论如何你都必须捕获它。我想 error_calback 必须用于执行特定于进程的清理。