Python 如何根据调用方为警告分配堆栈级别?
我有一个Python类,它在Python 如何根据调用方为警告分配堆栈级别?,python,python-3.x,constructor,warnings,Python,Python 3.x,Constructor,Warnings,我有一个Python类,它在\uuu init\uuu()中发出警告。它还提供用于打开和读取文件的factory类方法: 从警告导入警告 类别MyWarning(警告): “”“发现无效名称时发出警告。”“” 通过 类别MyClass: 定义初始化(self,名称): #简化;实际代码更长 如果无效(名称): 名称=固定名称(名称) 警告(f{names!r}包含无效元素), MyWarning,stacklevel=2) self.\u name=名称 @类方法 来自_文件的def(cls,文
\uuu init\uuu()
中发出警告。它还提供用于打开和读取文件的factory类方法:
从警告导入警告
类别MyWarning(警告):
“”“发现无效名称时发出警告。”“”
通过
类别MyClass:
定义初始化(self,名称):
#简化;实际代码更长
如果无效(名称):
名称=固定名称(名称)
警告(f{names!r}包含无效元素),
MyWarning,stacklevel=2)
self.\u name=名称
@类方法
来自_文件的def(cls,文件名):
打开(文件名)作为文件:
名称=提取名称(文件)
返回cls(名称)
stacklevel=2
使警告引用对MyClass()
的调用,而不是warn()
语句本身。当用户代码直接实例化MyClass时,这就起作用了。但是,当MyClass.from\u file()
发出警告时,MyWarning
指的是返回cls(名称)
,而不是从\u file()调用的用户代码
如何确保factory方法也发出指向调用方的警告?我考虑过的一些选择:
将一个“hidden”\u stacklevel
参数添加到\u init\u()
,并在\u stacklevel=2
中从文件()实例化MyClass。
- 这非常难看,并向API公开内部行为
添加一个“隐藏的”\u stacklevel
类属性,并在\uuuu init\uuuu()中访问它。然后在from_file()中临时修改该属性
- 也超级丑
添加一个\u set_names()
方法,用于检查/修复名称,并在需要时发出警告。然后在构造函数内调用此方法。对于from_file()
,首先用空参数实例化MyClass,然后直接调用\u set_names()
,以确保MyWarning指向调用者。
- 当调用文件()中的
时,仍然很有技巧,并且有效地调用了两次\u set\u names()
捕获并重新抛出警告,类似于异常链接。
- 听起来不错,但我不知道怎么做
我读了这本书,但它对安全捕捉和重新抛出警告几乎没有帮助。使用将警告转换为异常会中断MyClass()
,并迫使我再次调用它