情况:我的库中有一些自定义的异常类,用户在其代码中使用它们。出于某种原因,我想重命名其中一个例外并弃用旧例外。
将旧的异常保留为别名并不困难:
class MyNewError(ValueError):
pass
MyOldError = MyNewError
但最终我想删除我的库的旧错误名称,因此我希望在下游代码中使用此自定义异常的用户通过DeprecationWarning通知此错误将被删除。
但是我想在下面的用例中提出DeprecationWarning(比如我的包含自定义异常的库名为mypackage
):
# downstream user code
import mypackage
...
try:
....
except mypackage.MyOldError:
....
所以我想在用户尝试捕捉错误时提出警告,而不仅仅是当用户提出错误时。
有可能以某种方式做到这一点吗? (因为用户没有在这里调用我可以提出弃用警告的函数)
答案 0 :(得分:4)
您可以从this answer应用黑客/技巧,将您的模块转换为类并拦截__getattr__()
操作:
<强> mypackage的/ __初始化__吡啶强>:
import sys
import warnings
class MyNewError(ValueError):
pass
MyOldError = MyNewError
def foo():
print('mypackage.foo(): raising MyNewError')
raise MyNewError()
class Wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
if name == 'MyOldError':
warnings.warn('MyOldError is deprecated, use MyNewError')
return getattr(self.wrapped, name)
sys.modules[__name__] = Wrapper(sys.modules[__name__])
<强> test.py 强>:
import mypackage
try:
mypackage.foo()
except mypackage.MyOldError:
print('Caught mypackage.MyOldError')
<强>输出强>:
$ python test.py
mypackage.foo(): raising MyNewError
mypackage/__init__.py:18: UserWarning: MyOldError is deprecated, use MyNewError
warnings.warn('MyOldError is deprecated, please use MyNewError')
Caught mypackage.MyOldError
答案 1 :(得分:2)
当然可以在异常中引发异常,但如果用户不期望它,则可能会导致问题。假设这只是你帖子中的一个失误,并且你没有想要提出的DeprecationWarning
例外,你可以执行以下操作:
class MyOldError(MyNewError):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
deprecation_warning('Deprecated, please use MyNewError')
>>> raise MyOldError
Deprecated, please use MyNewError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
__main__.MyOldError
>>>