You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用__import__()导入本地模块?修改代码实现指定路径导入

解答你的三个问题:requests代码逻辑、__import__导入本地模块、实现目标导入效果

一、先搞懂requests/package.py里那段代码的逻辑

那段代码完全是为了向后兼容——说白了就是让老代码里写from requests.packages import urllib3这种写法还能正常跑,不用修改。咱们一步步拆:

  1. 第一部分:把第三方模块导入到当前模块的命名空间
for package in ('urllib3', 'idna', 'chardet'):
    locals()[package] = __import__(package)

这循环做的事,相当于手动写了import urllib3、import idna、import chardet,然后把这些模块对象放到当前requests.packages模块的本地命名空间里,这样在这个模块里直接写urllib3就能访问到对应的模块了。

  1. 第二部分:给这些模块及其子模块创建别名到requests.packages下
for mod in list(sys.modules):
    if mod == package or mod.startswith(package + '.'):
        sys.modules['requests.packages.' + mod] = sys.modules[mod]

sys.modules是Python保存所有已导入模块的字典。这段代码遍历所有已加载的模块,找到属于urllib3(或idna、chardet)及其子模块的条目,然后给它们在sys.modules里新增一个以requests.packages.开头的别名。比如原来的urllib3.connectionpool模块,现在会有一个requests.packages.urllib3.connectionpool的别名指向同一个模块对象。

这么做的核心目的是:老代码里如果写了from requests.packages.urllib3 import PoolManager,现在依然能正常工作——因为这个别名指向的就是真实的urllib3模块,身份完全一致(同一个对象),不会出现因路径不同导致的模块重复加载、状态不一致等奇怪问题。

二、用__import__()导入本地模块

__import__是Pythonimport语句背后实际调用的内置函数,导入本地模块要注意两个关键点:

基础用法(导入顶级模块)

如果只是导入最顶层的模块,直接传模块名就行:

# 等价于 import msazurensg
msazurensg = __import__('msazurensg')

导入子模块(重点)

如果要导入深层子模块(比如msazurensg.lib.urllib),必须指定fromlist参数,否则只会返回最顶层的模块:

# 等价于 import msazurensg.lib.urllib
urllib_mod = __import__('msazurensg.lib.urllib', fromlist=[''])
# 现在urllib_mod就是你封装的msazurensg.lib.urllib模块对象

要是想实现from msazurensg.lib import urllib的效果,可以这么写:

# 等价于 from msazurensg.lib import urllib
lib_module = __import__('msazurensg.lib', fromlist=['urllib'])
urllib = lib_module.urllib

简单说:fromlist参数会告诉__import__要返回的是子模块所在的父模块(或子模块本身),这样你才能拿到深层的子模块对象,而不是只拿到最顶层的包。

三、实现from msazurensg.lib import urllib的导入效果

要让用户能直接这么导入,最规范的做法是利用Python包的__init__.py文件:

  1. 确保你的目录结构正确
    你的项目结构应该是这样的:
msazurensg/
    __init__.py
    lib/
        __init__.py
        urllib.py  # 或者是一个urllib目录,里面有__init__.py
  1. 在msazurensg/lib/init.py里暴露urllib模块
    打开lib/__init__.py,添加一行:
from . import urllib

这样,当用户执行from msazurensg.lib import urllib时,Python会从lib包的命名空间里找到urllib这个模块对象——也就是你封装的那个版本。

如果你的urllib是在子目录里(比如lib/urllib/__init__.py),那同样在lib/__init__.py里写from .urllib import *或者from . import urllib就行,具体看你想暴露哪些内容。

内容的提问来源于stack exchange,提问作者Ahtesham Akhtar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:48