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

为何`from . import re`初始失败,执行`import re`后成功?(Python 3.7)

Python相对导入的诡异行为:3.7与3.8的差异解析

测试结果对比

Python 3.7.3(Debian 10.12)

$ python3
>>> from . import re
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 're' from '__main__' (unknown location)
>>> import re
>>> re
<module 're' from '/usr/lib/python3.7/re.py'>
>>> from . import re
>>> re
<module 're' from '/usr/lib/python3.7/re.py'>

首次执行相对导入失败,但导入re后再次执行却成功,这明显不符合预期。

Python 3.8.2(macOS 13.2)

>>> from . import re
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: attempted relative import with no known parent package
>>> import re
>>> re
<module 're' from '/Library/Developer/CommandLineTools/Library/Frameworks/
                   Python3.framework/Versions/3.8/lib/python3.8/re.py'>
>>> from . import re
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: attempted relative import with no known parent package
>>> re
<module 're' from '/Library/Developer/CommandLineTools/Library/Frameworks/
                   Python3.framework/Versions/3.8/lib/python3.8/re.py'>

这里无论是否提前导入re,相对导入都失败,提示没有已知父包。

底层机制与差异原因

  1. 相对导入的核心前提:相对导入依赖模块的__package__属性,只有当模块属于某个包时,该属性才会被正确设置,相对导入才能生效。交互式环境的主模块(__main__)默认没有有效__package__,所以正常情况下相对导入必然失败。

  2. Python 3.7的bug:当你导入re这类顶级模块后,Python 3.7会将主模块的__package__隐式设为空字符串""。此时from . import re会被解释为从“当前包的父级(即顶级命名空间)”导入re——而re已经在顶级命名空间存在,所以操作等价于import re,因此成功。这是违反相对导入设计逻辑的漏洞。

  3. Python 3.8的修复:3.8版本严格规范了__package__的处理逻辑,即使导入了顶级模块,主模块的__package__仍不会被设置为有效包名,因此所有相对导入都会直接抛出错误,这才是符合规范的行为。

总结

你在Python 3.7中看到的异常现象是解释器的bug导致的,Python 3.8及后续版本修复了这个问题,确保相对导入只能在包内部模块中使用,交互式主模块不允许执行相对导入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:14:58