我正在使用numpy.optimize.fsolve
进行一些计算。由于不恰当的初始值,其中一些计算会导致运行时警告
运行时警告:经过测量,迭代没有取得良好进展 通过最近十次迭代的改进 warnings.warn(msg,RuntimeWarning)
或
运行时警告:经过测量,迭代没有取得良好进展 通过最近五次雅可比评估的改进 warnings.warn(msg,RuntimeWarning)
由于我将所有初始值和所有结果写入文本文件(只是将stdout传递给文件),我想得到一个线索,计算上面提到的RuntimeWarnings的500步骤。
如numpy docs中所述,警告由Python's standard warnings module处理,但有没有办法在第一次运行时发生错误后停止或暂停计算?
答案 0 :(得分:2)
如果要在发出警告时终止计算,可以使用warnings
模块强制将某些类型的警告作为例外引发。你可以写下:
warnings.simplefilter('error')
这会将所有警告变为错误并立即停止该程序。缺点是只能通过捕获异常来恢复计算:它已经完成了。
如果您希望暂停该程序,您可以使用一点“黑客”来覆盖warnings
模块用来显示警告的功能。尽管我们目前的目的与文档的目的不同,但是文档明确允许覆盖此函数。这是一个简单的警告处理程序,询问用户是否继续。如果用户拒绝,则错误将提升为异常:
def handle_warning(message, category, filename, lineno, file=None, line=None):
print('A warning occurred:')
print(message)
print('Do you wish to continue?')
while True:
response = input('y/n: ').lower()
if response not in {'y', 'n'}:
print('Not understood.')
else:
break
if response == 'n':
raise category(message)
然后我们覆盖默认警告处理程序:
warnings.showwarning = handle_warning
现在我们尝试优化平面函数:
from scipy.optimize import fsolve
fsolve(lambda x: 1, 1)
我们几乎立即得到一条消息:
A warning occurred:
The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
Do you wish to continue?
y/n:
如果我们回答y
,将允许优化继续并返回其结果。如果我们回答n
,则会引发异常并终止计算。
或者,如果您不想覆盖模块级别的showwarning
函数,则可以使用上下文管理器。我们可以将它放在一个包装好的和整洁的函数中:
def pause_if_warning(function, *args, **kwargs):
with warnings.catch_warnings():
warnings.showwarning = handle_warning
return function(*args, **kwargs)
所以我们现在可以写:
pause_if_warning(fsolve, lambda x: 1, 1)
获得与上述相同的行为。