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

为何__init__.py中相对导入的foo在pkg命名空间存在却在pkg.bar中未定义?

问题背景

我编写了一个包含两个子模块的Python包,结构如下:

pkg/__init__.py
pkg/foo.py
pkg/bar.py

我在__init__.py和bar.py中都放入了以下代码:

from . import foo as f
foo
print("Hello!")

导入pkg可成功执行:

>>> import pkg
Hello!

但导入pkg.bar时失败:

>>> import pkg.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\fumito\Documents\pkg\bar.py", line 2, in <module>
    foo
NameError: name 'foo' is not defined

请问为何foo在pkg命名空间中已定义,但在pkg.bar命名空间中未定义?

原因及解决方法

核心原因:模块命名空间完全独立

Python里每个模块(包括包的__init__.py和子模块bar.py)都有自己独立的命名空间,彼此之间不会自动共享变量或名称,所有引用都必须显式导入。

  1. 关于pkg命名空间中的foo
    当你执行import pkg时,Python加载pkg/__init__.py,其中的from . import foo as f会触发两个行为:
  • 将foo模块导入到__init__.py的命名空间中,并命名为f;
  • 同时Python会把foo模块自动注册到pkg包的全局命名空间里,所以pkg.foo是可访问的,但这只存在于包的命名空间,和bar.py无关。
  1. 关于pkg.bar中的foo未定义
    在bar.py里,你写的from . import foo as f只是把foo模块导入并绑定到了名称f上,当前模块的命名空间里只有f,没有foo这个名称。所以当你直接写foo时,Python找不到这个名称,自然抛出NameError。

解决方法

如果要在bar.py中使用foo这个名称,修改代码为:

from . import foo
foo
print("Hello!")

或者继续使用别名,改用f访问:

from . import foo as f
f
print("Hello!")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:53:08