Mat*_*GdV 5 python lazy-loading python-import
所以,让我们假设我有一个包含 20 个逻辑分离模块的库代码的 python 包,我想从每个模块中选择 1 或 2 个类作为包的公共 api。与其强迫用户直接从模块中导入这些类,我想让它们直接从包的命名空间中使用,在__init__.py
.
但是我不希望每次都急切地加载所有内容,因为每当有人试图从单个类访问一个类时加载所有 20 个模块是一种巨大的浪费(其中一些包含自己昂贵的导入),所以我实现了一个__getattr__()
根据https://www.python.org/dev/peps/pep-0562/ 进行模块级别,并在有人尝试导入该类时使用其中的 importlib 加载给定类的模块。
这是一个相对干净的解决方案,但让它成为噩梦的部分是这绝对杀死了 Jedi 或 PyCharm 等静态代码分析工具。自动完成和光标悬停文档字符串对我来说意义重大,因为它们极大地提高了生产力,所以我不想编写 IDE 无法理解的库代码。
我可以编写打字存根,但这会增加更多的维护负担,因为实际上我已经对所有代码进行了类型注释并带有内联文档字符串。这不是一个很好的解决方案。
有谁知道我还能怎么做?我希望有一些聪明的方法来解决这个问题,我只是没有想过。
小智 0
这是一个老问题,但如果其他人遇到这个问题,我使用 VSCode + Sublime 静态分析的解决方案如下:
import importlib
import pathlib
# this is used instead of typing.TYPE_CHECKING as it avoids needing to import
# the typing module at all
_typing = False
if _typing:
import sub_package
del _typing
def __getattr__(name: str):
current_file = pathlib.Path(__file__)
current_directory = current_file.parent
for path in current_directory.iterdir():
if path.stem != name:
continue
return importlib.import_module(f"{__package__}.{name}")
raise AttributeError(f"{__package__} has no attribute named: {name}")
__all__ = ("sub_package",)
Run Code Online (Sandbox Code Playgroud)
我认为OP缺少的是暴露__all__
变量
归档时间: |
|
查看次数: |
65 次 |
最近记录: |