Python 以嵌套结构导入
Python imports in nested structure
有如下结构:
project/
I-----main.py
I-----src/
I----__init__.py (empty)
I----util.py
I----shared/
I----__init__.py (empty)
I----hello.py
#main.py
from src import util
#util.py (runs without errors)
from shared import hello
#hello.py (runs without errors)
def hello():
print("Hello")
我尝试运行main.py,得到结果
ModuleNotFoundError: No module named 'shared'
如何在 main.py 中修复导入?
你可能想要 from src.shared import hello
您需要使用相对导入:
from .shared import hello
如果您 运行 util.py
正常,.../project/src
附加到 sys.path
并且 Python 可以找到导入。但是,当你 运行 main.py
时, .../project/
附加到 sys.path
,并且 Python 找不到 shared
模块。通过使用相对导入,Python 查找相对于当前包的模块名称,可以找到 shared
模块。
另请参阅:Relative imports for the billionth time
造成此类故障的主要原因有两个:
模块导入: 您没有正确导入模块。您可以通过提及其子模块的导入使用模块的 __init__.py
导入它,也可以通过导入直接放置完整路径。例如,您可以使用 from src.shared import hello
。或者,在 __init__.py
文件中的 src
模块中,您可以添加 from shared import hello
。这也将起作用,因为每当您导入模块时,该模块中第一个 运行 就是该文件的 __init__.py
。
Circular imports: 这不是你的情况,但我提出这个问题是因为很多时候我们忽略了这一点并陷入困境。当两个模块相互依赖时,就会发生循环导入。我已经在 post、What is Circular Import and how to avoid it.
中描述了它发生的原因以及如何避免它
我找到了可能的解决方案(效果很好):
#util.py
import sys
from pathlib import Path
root = Path(__file__).parent.parent #depends on file's place in general structure
sys.path.append(str(root))
import src.shared.hello as hello
有如下结构:
project/
I-----main.py
I-----src/
I----__init__.py (empty)
I----util.py
I----shared/
I----__init__.py (empty)
I----hello.py
#main.py
from src import util
#util.py (runs without errors)
from shared import hello
#hello.py (runs without errors)
def hello():
print("Hello")
我尝试运行main.py,得到结果
ModuleNotFoundError: No module named 'shared'
如何在 main.py 中修复导入?
你可能想要 from src.shared import hello
您需要使用相对导入:
from .shared import hello
如果您 运行 util.py
正常,.../project/src
附加到 sys.path
并且 Python 可以找到导入。但是,当你 运行 main.py
时, .../project/
附加到 sys.path
,并且 Python 找不到 shared
模块。通过使用相对导入,Python 查找相对于当前包的模块名称,可以找到 shared
模块。
另请参阅:Relative imports for the billionth time
造成此类故障的主要原因有两个:
模块导入: 您没有正确导入模块。您可以通过提及其子模块的导入使用模块的
__init__.py
导入它,也可以通过导入直接放置完整路径。例如,您可以使用from src.shared import hello
。或者,在__init__.py
文件中的src
模块中,您可以添加from shared import hello
。这也将起作用,因为每当您导入模块时,该模块中第一个 运行 就是该文件的__init__.py
。Circular imports: 这不是你的情况,但我提出这个问题是因为很多时候我们忽略了这一点并陷入困境。当两个模块相互依赖时,就会发生循环导入。我已经在 post、What is Circular Import and how to avoid it.
中描述了它发生的原因以及如何避免它
我找到了可能的解决方案(效果很好):
#util.py
import sys
from pathlib import Path
root = Path(__file__).parent.parent #depends on file's place in general structure
sys.path.append(str(root))
import src.shared.hello as hello