我已经编写了一个包,其中一个子模块包含了我想要删除的模块级变量deprecated_var
,因为这是一个可怕的错误。
mypkg
- mymodule
- __init__.py
但是,我不想只让我的最终用户拥有一个通用的ImportError
,我想打印一条消息,说明他们的导入是不推荐的,以及他们应该做什么。因此,与其:
>>> from mypkg.mymodule import deprecated_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'deprecated_var'
我希望用户看到这样的东西:
>>> from mypkg.mymodule import deprecated_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: mypkg.mymodule.deprecated_var was removed. Replace
with "from foo.bar import Baz; deprecated_var = Baz()"
我怎样才能做到这一点?
发布于 2018-08-20 06:24:38
在python3.7之前,我认为这是不可能的。
但是,在python3.7或更高版本中,这可以通过使用在__getattr__
中添加的模块级PEP562来实现。
你会这样用:
#_deprecated_vars is a dict of keys -> alternatives (or None)
_deprecated_vars: Dict[str, Optional[str]] = {
'deprecated_var': 'from foo.bar import Baz; deprecated_var = Baz()',
'other_deprecated_var': None
}
def __getattr__(name):
if name in _deprecated_vars:
alt_text = '{name} was removed from module {__name__}'
replace_text = _deprecated_vars[name]
if replace_text is not None:
alt_text += f'. Replace with {replace_text!r}.'
raise AttributeError(alt_text)
raise AttributeError(f"module {__name__} has no attribute {name}")
但是,我不确定这是否适用于from a.b import deprecated_var
的用例。这是关于import a.b; a.b.deprecated_var
的更多内容。见前者的另一个答案。
发布于 2018-08-20 06:29:16
对于特定的示例,可以使用以下方法:
mymodule/__init__.py
#deprecated_var = 5
replacement_var = 6
mymodule/deprecated_var.py
raise ImportError("deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead")
当直接导入变量时,这会引发自定义ImportError
:
>>> from mymodule import deprecated_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../mymodule/deprecated_var.py", line 1, in <module>
raise ImportError("deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead")
ImportError: deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead
当作为模块属性访问它时,它什么也不做。或者更确切地说,它抛出一个AttributeError
而不是一个弃用警告:
>>> import mymodule
>>> mymodule.deprecated_var
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'mymodule' has no attribute 'deprecated_var'
https://stackoverflow.com/questions/51932222
复制相似问题