任务
对于暗示使用不同包(例如 pandas、numpy 等)的给定代码块,我需要检索创建的所有警告的列表。
部分解决方案
使用
warnings.catch_warnings(record=True)
我能够“捕获”列表中的所有警告,但是因为执行 warnings.warn
时堆栈级别几乎总是 2,这意味着我只能获得对调用者的引用,而不是调用 warnings.warn
的确切代码段(有了它就很容易提取包名称)
当前解决方案
使用上下文管理器,我可以围绕 warnings.warn 方法构建一个包装器,以便我能够挂钩它并获取该列的原始文件/包。
class MyWarningsCtx:
def __enter__(self):
self.old_warn = warnings.warn
self.warnings = []
#
def new_warn(*args, **kwargs):
frame = inspect.stack()[1]
p = frame[0].f_code.co_filename
obj = {"message": args[0], "path": p}
self.warnings.append(obj)
self.old_warn(*args, **kwargs)
warnings.warn = new_warn
return self.warnings
def __exit__(self, exc_type, exc_val, exc_tb):
warnings.warn = self.old_warn
为了测试这一点,我使用以下内容
if __name__ == "__main__":
df = pd.DataFrame([['1990', 'a', 5, 4, 7, 2], ['1991', 'c', 10, 1, 2, 0], ['1992', 'd', 2, 1, 4, 12], ['1993', 'a', 5, 8, 11, 6]],
columns=('Date', 'best', 'a', 'b', 'c', 'd'))
df.lookup(df.index, df['best'])
print("\n\n\n\n")
with MyWarningsCtx() as wrngs:
df.lookup(df.index, df['best'])
print("\n\n\n\n")
print({"parsed_warnings": wrngs})
path_to_current_folder/test_ctx_warnings.py:30: FutureWarning: The 'lookup' method is deprecated and will beremoved in a future version.You can use DataFrame.melt and DataFrame.locas a substitute.
df.lookup(df.index, df['best'])
path_to_env/site-packages/pandas/core/frame.py:4553: FutureWarning: The 'lookup' method is deprecated and will beremoved in a future version.You can use DataFrame.melt and DataFrame.locas a substitute.
warnings.warn(msg, FutureWarning, stacklevel=2)
{'parsed_warnings': [{'message': "The 'lookup' method is deprecated and will beremoved in a future version.You can use DataFrame.melt and DataFrame.locas a substitute.", 'path': '/path_to_env/site-packages/pandas/core/frame.py'}]}
现在有几件事我希望你能帮助我:
inspect
来获取文件。但即使我不使用inspect
也没关系。即使我只做了这样的事情(如下),我仍然会得到 warnings.warn
调用的确切行。不知道我错过了什么def new_warn(*args, **kwargs):
self.old_warn(*args, **kwargs)