假设我有一个如下所示的文件夹结构:

.
├── A
│   ├── a.py
│   └── b.py
└── main.py

这些文件具有以下内容:

b.py:

class BClass:
    pass

a.py:

from b import BClass

主要.py:

from A import a

如果我跑 python3.3 A/a.py 或者 python3.3 B/b.by, ,没有错误。但是,如果我跑 python3.3 main.py, ,出现以下错误:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    from A import a
  File "/tmp/python_imports/A/a.py", line 1, in <module>
    from b import BClass
ImportError: No module named 'b'

将 a.py 中的导入行更改为 import A.b 有效,但显然 python3.3 A/a.py 那么就会失败。我其实对跑步并不感兴趣 python3.3 A/a.py 但我希望该模块可以从多个位置导入。因此,无论 a.py 在哪里导入,a.py 都应该导入 b.py。

如何解决这个问题?

有帮助吗?

解决方案

除了 __init__.py 我在评论中提到这对于软件包是强制性的,您需要相对导入同级模块:

from .b import BClass

然后它也可以在 Python 3 中运行。

或者,您当然可以导入全名:

from A.b import BClass

但是这样你的模块就不能在你的包树中轻松地重新定位。

但无论哪种方式,您都可以使用 a.py 作为一个独立的。为了实现这一点,你需要包围 import 声明与 try/except 并尝试不同的版本,以防第一个版本失败:

try:
  from .b import BClass
except ValueError:
  from b import BClass

但这是可以理解的。在较大的系统中,模块可能依赖于其他模块 某处 在包中,否则它们可能不应该是包的一部分,而是独立的。如果存在这样的依赖关系,那么像独立模块一样使用模块当然会出现问题。

其他提示

你需要一个 __init__.py 文件(空就可以了)在 A 目录。否则,python 不会将其识别为包。

现在你的 A 是一个包,你应该使用绝对导入或显式相对导入。在这种情况下,在 A/a.py 要么使用 from A.b import BClass 或者 from .b import BClass.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top