Python - 从子文件夹进行绝对导入

14

基本上我正在询问与此人相同的问题:如何在Python中进行相对导入?

但没有人给他正确的答案。如果您在子文件夹中,希望进入上级目录,然后进入另一个子文件夹,那么按照他们建议的做法是行不通的(正如OP在其评论中指出的那样)。

我知道可以使用sys.path来做到这一点,但我更喜欢更清洁的方法。

例如:

App
__init__.py
Package_A
--__init__.py
--Module_A.py
Package_B
--__init__.py
--Module_B.py

我该如何将Module_A导入Module_B?


你所说的“Module_A”是指“Package_A”吗?一个包含有 "init.py" 和可能还有其他模块的文件夹被称为包。你能否将你的“Module_A”和“Module_B”重写为“Package_A”和“Package_B”,这样你的问题会更加清晰明了吗? - S.Lott
3个回答

12
main.py
setup.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       module_a.py
    package_b/ ->
       __init__.py
       module_b.py
  1. 执行python main.py.
  2. main.py导入了app.package_a.module_a
  3. module_a.py导入了app.package_b.module_b

另一种方法是在2或3中使用:from app.package_a import module_a

只要在PYTHONPATH中有app,这样就可以工作。然后,main.py可以放在任何地方。

因此,您编写一个setup.py将整个应用程序包和子包复制(安装)到目标系统的Python文件夹,以及将main.py复制到目标系统的脚本文件夹。


最重要的是在每个目录中添加适当的__init__.py文件,并在导入语句中包含app。如果这样做,将import app.package_a.module_a行添加到module_b.py应该会进行适当的导入。基本上,第三步是您想要的,除非您计划分发软件包,否则其余步骤都是多余的。 - Nick Crawford

2
如果我阅读正确,在Python 2.5或更高版本中:
from ..Module_B import Module_B

我以为我精通Python,但我不知道在2.5版本中是可能的。

这是正确的。虽然有点丑,但通常绝对导入是最好的选择,除非在特殊情况下。 - bobince
2
这个不工作,我得到了“尝试在非包中进行相对导入”的错误。 - ryeguy
假设该语句位于Module_A.py中(并且在后期编辑中应该来自..Package_B)。相对导入是基于您所在的模块的包路径,而不是目录;您无法从顶级脚本或简单模块中使用它们。 - bobince

0
如果您正在将Module_B导入到App中,则应该这样做:
Module_B.py: import ModuleA
App.py(也导入了ModuleA,现在默认在您的Pythonpath中)
import Module_B.Module_B

另一种选择是更新__init__.py文件(位于Module_A / App文件夹中)如下:
import os
import sys
sys.path.extend('%s../' % os.getcwd())
import ModuleA

另一种选择是将您的文件夹添加到PYTHONPATH环境变量中。

在运行时修改 sys.path 几乎总是不正确的。它很脆弱,表明包结构不良好。 - habnabit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接