Python实现自动启用惰性导入的实战指南

 更新时间:2026年04月07日 09:11:27   作者:RockByte  
Python 3.15 引入了一个新特性:lazy imports(惰性导入),它为加载缓慢的模块提供了一种更高层次、也更正式的解决方案,下面小编就和大家详细介绍一下如何在Python中动启用惰性导入吧

不用再等待慢吞吞的模块加载,也不用继续依赖临时性的绕路写法:Python 3.15 新特性 —— lazy imports 机制已经给出了更直接的解法。

我们知道,在 Python 中导入模块时,解释器必须先把这个模块的代码完整求值,程序才能继续往下执行。

对大多数模块来说,听起来没什么问题。

但如果某个模块的启动过程很长、很重,那么程序就会在导入它的那一刻被拖慢。

以前,Python 开发者通常会通过调整导入位置来绕开这个问题,让导入只在真正需要时才发生。

最常见的做法就是把 import 放进函数体里,而不是写在模块顶层。

不过,这终究是一种不太优雅的权宜之计,也会让程序流程变得更难梳理。

Python 3.15 引入了一个新特性:lazy imports。

它为加载缓慢的模块提供了一种更高层次、也更正式的解决方案。

当一次导入被声明为“惰性”时,它不会在第一次导入时立刻求值,而是等到第一次真正被使用时才求值。

这样一来,慢速导入的成本就可以被推迟到真正需要那段代码的时候再支付。

而且,虽然惰性导入带来了新语法,你依然可以提前让现有代码适配它,而不必大面积改写既有的导入语句。

立即与惰性

要理解惰性导入解决了什么问题,最好的方式还是先看一个例子。

开发者应该经常这样写代码,假设同一个目录下有这样两个文件:

# main.py
print("Program starting")
from other import some_fn
print("Other module imported")
some_fn()
print("Program ended")

# other.py
print("Other module evaluation started")
from time import sleep
sleep(2)
# ^ This simulates a slow-loading module
print("Other module evaluation ended")

def some_fn():
    print("some_fn run")

如果运行 main.py,输出大概会是这样:

Program starting
Other module evaluation started

[two-second delay]

Other module evaluation ended
Other module imported
some_fn run
Program ended

仅仅因为导入了 other,程序就几乎被卡住了。

甚至在我们真正调用导入进来的函数之前,更别说继续执行后续逻辑之前,这段等待就已经发生了。

现在把 main.py 改成使用惰性导入,再看看会发生什么。

这只适用于 Python 3.15 或更高版本。

print("Program starting")
lazy from other import some_fn
print("Other module imported")
some_fn()
print("Program ended")

这时再运行程序,行为就会发生变化:

Program starting
Other module imported
Other module evaluation started

[two-second delay]

Other module evaluation ended
some_fn run
Program ended

现在,导入本身已经不会造成任何延迟。

真正的等待,只有在我们调用那个导入进来的函数时才会出现。

那底层到底做了什么?

当 Python 识别到惰性导入时,通常是因为导入语句前面出现了 lazy 关键字,就像上面的例子那样,它不会走平常的导入流程。

取而代之的是,它会为被导入的模块创建一个“代理对象”,也就是一个占位用的替身。

这个代理会一直待命,直到程序真的开始对这个模块做某些操作。

到了那一刻,真正的导入才会触发,模块也才会被求值。

如果你想把某一行导入声明成惰性导入,那么 lazy 必须始终是该行的第一个词:

# lazily imports foo
lazy import foo
# lazily imports bar from foo
lazy from foo import bar
# same with the use of "as":
lazy import foo as foo1
lazy from foo import bar as bar1

用在哪里

惰性导入最常见的用途,就是替代那些为了避免启动阶段高成本导入而写出来的传统变通方案。

正如前面提到的,把导入写在函数内部而不是模块顶层,的确能让导入只在函数执行时才发生。

但这样做也带来了另一个问题:这个导入只存在于函数作用域内。

因此,除非你再叠加另一层绕路方案,否则模块里的其他代码都没法直接使用它。

而使用惰性导入后,你依然可以把导入保留在模块顶层,就像平常那样写。

你唯一需要做的,只是在代码前面加上 lazy 关键字。

自动启用惰性导入

你还可以在现有代码库里自动启用惰性导入,而不必逐条改写 import 语句。

Python 3.15 为 sys 模块新增了一些能力,用来控制惰性导入的行为。

例如,你可以通过编程方式声明:从程序执行的某个时间点开始,之后所有导入都采用惰性方式处理。

import sys
sys.set_lazy_imports("all")

如果给 sys.set_lazy_imports() 传入 "all",那么从那一刻起,程序中的每一次导入都会变成惰性导入,不管它是否显式写了 lazy 关键字。

如果(给该函数)传入 "normal",则只有显式声明的才会惰性导入

如果传入 "none",则彻底关闭惰性导入。

以编程方式控制惰性导入

你也可以在运行时接管惰性导入的行为。

这样一来,你就能够进一步控制到底哪些模块会被惰性导入。

import sys

def mod_filter(importing, imported, fromlist):
    return imported == "module"

sys.set_lazy_imports_filter(mod_filter)

sys.set_lazy_imports_filter() 允许你传入一个函数,这个函数会接收三个参数:

  • 发起导入的模块
  • 被导入的模块
  • 被导入名称组成的列表

借助这个函数,你可以写出自己的判断逻辑:返回 True 时,允许某次导入按惰性方式进行;返回 False 时,则强制它按普通方式立即导入。

这样,你既可以在测试里为惰性导入维护允许列表和阻止列表,也可以把这套规则直接纳入程序自身的运行机制。

使用惰性导入的两种方式

Python 一直以来都很重视让新特性能平滑进入已有代码库。

惰性导入同样可以按这种方式接入。

你可以在程序启动时先检查这个能力是否存在,然后再通过 sys.set_lazy_imports() 自动把惰性导入应用到整个项目中。

最直接的办法,是先判断 Python 版本号:

import sys
if sys.version_info >= (3, 15):
    ...  # set up lazy imports

或者,也可以直接检查 sys 中是否提供了这些惰性导入控制接口:

import sys
if hasattr(sys, "set_lazy_imports"):
    ...  # set up lazy imports

到此这篇关于Python实现自动启用惰性导入的实战指南的文章就介绍到这了,更多相关Python惰性导入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python 实现屏幕录制示例

    python 实现屏幕录制示例

    今天小编就为大家分享一篇python 实现屏幕录制示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Python实现高斯函数的三维显示方法

    Python实现高斯函数的三维显示方法

    今天小编就为大家分享一篇Python实现高斯函数的三维显示方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • python带参数打包exe及调用方式

    python带参数打包exe及调用方式

    今天小编就为大家分享一篇python带参数打包exe及调用方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • python3中No module named _ssl的问题解决

    python3中No module named _ssl的问题解决

    本文主要介绍了python3中No module named _ssl的问题解决,这个错误表示Python导入_ssl模块时失败,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 利用Python实现去重聚合Excel数据并对比两份数据的差异

    利用Python实现去重聚合Excel数据并对比两份数据的差异

    在数据处理过程中,常常需要将多个数据表进行合并,并进行比对,以便找出数据的差异和共同之处,本文将介绍如何使用 Pandas 库对两个 Excel 数据表进行合并与比对,需要的可以参考下
    2023-11-11
  • python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例

    python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例

    这篇文章主要介绍了python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例,需要的朋友可以参考下
    2020-03-03
  • Python 如何展开嵌套的序列

    Python 如何展开嵌套的序列

    这篇文章主要介绍了Python 如何展开嵌套的序列,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • 使用python实现群发微信消息的工具

    使用python实现群发微信消息的工具

    如果您想批量向微信好友发送相同的内容,手动一个个操作非常费时费力,这时候可以用Python实现自动化处理,更加高效方便,下面小编就来和大家讲讲具体操作吧
    2025-05-05
  • 使用Python抓取豆瓣影评数据的方法

    使用Python抓取豆瓣影评数据的方法

    今天小编就为大家分享一篇关于使用Python抓取豆瓣影评数据的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Python3 requests文件下载 期间显示文件信息和下载进度代码实例

    Python3 requests文件下载 期间显示文件信息和下载进度代码实例

    这篇文章主要介绍了Python3 requests文件下载 期间显示文件信息和下载进度代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08

最新评论