我的程序有这样的结构:
scripts/
__init__.py
mod1.py
mod2.py
sub1/
__init__.py
mod3.py
sub2/
__init__.py
mod4.py
所有程序都以mod1.py
启动,根据提供的系统参数选择要运行的后续脚本(mod3/mod4.py
)。因此导入时的顶级目录为scripts/
。
说我运行我的程序,>mod1.py 3
执行sub1.mod3
。在mod3
内我需要mod2
中定义的函数(该模块保存mod3/mod4
的重用代码块)。
当我尝试from .. import mod2
时,我得到的ValueError
我试图在顶级目录之外进行相对导入。我在语法上引用docs,如果我们将它与我的情况进行比较,mod3.py
将是当前模块(在mod1.py
之后)调用它。
我如何尝试进行相对进口有什么问题?
mod1.py :
import sys
def imp(module):
m = __import__(module) # equivalent to import module as m
m.start()
if __name__ == '__main__':
mods = {'3': 'sub1.mod3',
'4': 'sub2.mod4'}
imp(mods[sys.argv[1]])
mod3.py
from .. import mod2 # fails
import mod2 # works; guessing since import considers mod1 location top-level
.
.
.
def start():
# do stuff
答案 0 :(得分:2)
你说:
所有程序都以mod1.py启动,它根据提供的系统参数选择运行哪个后续脚本(mod3 / mod4.py)。因此导入时的顶级目录是scripts /。
From the docs(6.4.2包内引用):
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为“__main__”,因此用作Python应用程序主模块的模块必须始终使用绝对导入。
因此您必须在文件中使用绝对导入。
所以你的代码应该是
from scripts.mod2 import X
或
from scripts import mod2
此外,我不确定你为什么要这样做。
将两个模块保存在单独的包中并使用if
条件加载它们会更简单,同时将文件保存在同一目录中,没有__init__.py
:
if sys.argv[1] == '3':
import mod3
elif sys.argv[2] == '4':
import mod4
如果必须将它们保存在单独的文件夹中,请使用此结构:
scripts/
mod1.py
pkg/
__init__.py
mod2.py
sub1/
__init__.py
mod3.py
sub2/
__init__.py
mod4.py
使用此结构,您的相对导入应该有效。然后导入:
if sys.argv[1] == '3':
from pkg.sub1 import mod3
elif sys.argv[2] == '4':
from pkg.sub2 import mod4
值得注意的是,无论您导入的库或软件包的哪个部分,整个软件包都会被导入 - 它只是在范围内不可用。