Python模块加载机制与重载详解

小岛来信
小岛来信
发布时间:2026-10-13 | 4人浏览过
原创

本文详细解析Python中import语句的工作机制,涵盖模块搜索、编译生成.pyc文件及执行三个阶段。重点介绍模块搜索路径的优先级顺序,包括主目录、PYTHONPATH环境变量、标准库及.pth文件。针对代码修改后未生效的问题,讲解如何使用内置reload函数实现模块重载,并提示相关注意事项。

无论是使用import语句还是from mmmm import *的方式导入模块,当程序运行结束后,回头查看存储mmmm.py文件的目录,会发现多出了一个文件。

$ ls mmm*
mmmm.py mmmm.pyc

在该目录下,除了原有的mmmm.py文件外,还多生成了一个mmmm.pyc文件。这个文件并非手动编写,而是由import导入过程自动生成的。

接下来分析import的工作流程。

执行import mmmm时,Python并非简单地将mmmm.py文件装载到当前作用域,而是首先执行一次运算。首次导入mmmm.py时,Python会先对其进行编译,生成扩展名为.pyc的同名文件,随后才执行mmmm模块的代码并创建相应对象。这就像把大象装进冰箱,需要执行三个步骤:

  • 第一步是搜索。Python需要定位并找到被import的模块文件,具体查找方式将在下文详述。
  • 第二步是编译。找到模块文件后,Python将其编译为字节码,即生成.pyc文件(关于字节码的详细介绍请继续阅读)。需要注意的是,并非每次都会编译,仅在首次运行时进行编译。如果mmmm.py文件发生修改,Python会将其视为新文件并重新编译。具体机制是.pyc文件中包含时间戳,Python会自动检查该时间戳:若.pyc文件的时间戳比同名的.py源文件旧,则重新编译;否则跳过编译步骤。此外,如果系统中仅存在字节码文件.pyc而找不到同名的.py源文件,Python将直接运行该字节码文件。
  • 第三步是运行。执行前面已编译好的模块字节码文件,这是顺理成章的执行过程。

下面详细介绍模块搜索机制。

通常情况下,Python会自动完成模块搜索过程。但在某些特定场景下,可能需要程序员手动设定搜索路径。当执行import导入模块时,Python会按照以下顺序查找目标模块文件:

  1. 首先是程序的主目录。在前一讲中,若在codes目录下运行交互模式,此时主目录即为codes。当在该交互模式中执行import mmmm时,Python会首先在codes目录中搜索相应文件(找到.py文件后编译为.pyc)。在后续网页编程场景中,主目录可通过顶层配置文件进行设置。
  2. 其次是PYTHONPATH目录。这是一个通过环境变量设置的目录,若未设置该环境变量,则忽略此步骤。关于如何设置环境变量,建议通过搜索引擎查询具体方法。
  3. 第三是标准库目录。这是随Python安装过程自动部署到计算机中的目录。
  4. 最后是.pth文件的内容。若存在此类文件,Python会在其中进行最后搜索。这是一种简便方法,通过在.pth文件中添加有效目录路径,可将其纳入搜索范围。下图展示了本人计算机上存放.pth文件的位置以及其中包含的.pth文件内容。

用户也可以自行编写.pth文件,在其中指定搜索目录并保存至相应位置。例如,打开目录中的easy-install.pth文件,可以看到其具体内容如下。

模块搜索即为此过程。此处建议初学者仅了解原理即可,无需急于进行手动设置,因为在多数情况下Python均可自动完成搜索。特别是对于初学者,建议暂勿轻易修改相关配置。

接下来讨论模块重载机制。

以mmmm模块为例进行说明。

在一个Shell环境中启动Python,并执行以下操作:

>>> import mmmm
>>> mmmm.web
'https://hiekay.github.io'

随后,打开另一个Shell环境,编辑mmmm.py文件,对web变量的值进行适当修改:

#!/usr/bin/env python
#coding:utf-8
web = "https://hiekay.github.io, I am writing a python book on line. "
def my_name(name):
  print name
class pythoner:
  def __init__(self,lang):
    self.lang = lang
  def programmer(self):
    print "python programmer language is: ",self.lang

保存修改后,切换回之前导入了模块的交互模式:

>>> mmmm.web
'https://hiekay.github.io'

此时输出结果与修改前一致,没有任何变化。这是为什么呢?

原因在于,当导入模块时,Python仅在第一次导入时加载并执行模块代码,后续再次导入不会重新加载或执行。因此,即使模块代码已修改,当前执行的仍是修改前的版本。

如何实现代码修改后执行新版本呢?一种方式是退出当前交互模式,重新进入并再次执行import mmmm。这种方法较为繁琐。Python提供了另一个函数——reload函数,用于实现模块的重新加载(简称重载),重载后模块代码将重新执行。具体操作如下:

>>> reload(mmmm)
<module 'mmmm' from 'mmmm.py'>
>>> mmmm.web
'https://hiekay.github.io, I am writing a python book on line. '

执行后,即可显示修改后的内容。

特别提醒注意以下事项:

  • reload是Python的内置函数。
  • 调用格式为reload(module),其中module参数必须是一个已存在的模块对象,而非模块名的字符串变量。

总结。

以上就是本文的全部内容,希望本文的内容对大家的学习或工作具有一定的参考借鉴价值,感谢支持。如需了解更多相关内容,请查看相关链接。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表