Python的PEP 690类似延迟导入
项目描述
lazy-imports-lite 改变了Python导入的语义,并在首次使用时延迟导入,类似于PEP 690。
我喜欢延迟导入的想法,并想在项目中使用它们而不必更改我的代码。希望这个项目能让更多人能在他们的项目中使用延迟导入。
[!NOTE] 需要注意的是,该项目与原始PEP没有任何关联。希望这个项目能更广泛地采用延迟导入,但目前没有标准化计划。
[!IMPORTANT] lazy-imports-lite 仍处于早期开发阶段,可能存在错误。在使用之前,请务必仔细测试您的代码。
主要功能
- 延迟导入几乎像PEP 690
- 不需要更改代码
- 可以按模块启用(通过包中的关键字)
它与PEP 690有什么不同?
- 它的性能不如PEP的实现。对导入模块部分的每次访问都会转换为属性访问
x
->x._lazy_value
。 - 延迟导入期间发生的异常将被转换为
LazyImportError
。 - 使用
exec
或eval
的模块无法转换。
使用方法
- 将
lazy-imports-lite
添加到您的项目依赖中。 - 将 lazy-imports-lite-enabled 添加到
pyproject.toml
的关键字中。[project] keywords=["lazy-imports-lite-enabled"]
这将为您的项目中模块的所有顶层导入启用延迟导入。验证其是否启用的一种方法是检查使用的加载器。
>>> import your_project
>>> print(type(your_project.__spec__.loader))
<class 'lazy_imports_lite._loader.LazyLoader'>
实现
lazy-imports-lite
通过在代码编译前运行时重写AST来工作。
以下代码
from foo import bar
def f():
print(bar())
内部转换为
import lazy_imports_lite._hooks as __lazy_imports_lite__
globals = __lazy_imports_lite__.make_globals(lambda g=globals: g())
bar = __lazy_imports_lite__.ImportFrom(__package__, "foo", "bar")
def f():
print(bar._lazy_value())
这种转换不应该对您(源位置被保留)可见,但如果某些事情没有按预期工作,了解这一点是好的。
如果您想了解代码将如何更改,可以使用 lazy-imports-lite 预览 <filename>
查看此转换的预览。
待办事项
- 可变的
globals()
- 缓存生成的字节码
问题
如果您遇到任何问题,请提交问题,并附上详细描述。
许可
根据MIT许可证分发,“lazy-imports-lite”是免费和开源软件。