我是Python的新手。这真让我感到困惑!
我的目录结构是这样的:
Project
| - subpackage1
|- a.py
| - subpackage2
|- b.py
| - c.py
当我将a.py
的{{1}}导入b.py
时,会收到 ModuleNotFoundError 。看来我无法从父目录导入文件。
某些解决方案建议在每个目录中添加一个空文件from subpackage1 import a
,但这不起作用。解决方法是,将以下内容放入每个子文件(即__init__.py
和a.py
)中,以访问父目录:
b.py
我试图在子文件中输出import os
import sys
sys.path.append(os.path.abspath('..'))
,它仅包含当前文件路径和anaconda路径,因此我必须将sys.path
附加到..
。
如何解决此问题?有没有更有效的方法?
答案 0 :(得分:1)
您遇到的第一个问题是由于from subpackage1 import a
模块中的b.py
行。
b.py
位于您的subpackage2
软件包中,这是subpackage1
的同级软件包。因此,尝试运行from subpackage1 import a
意味着subpackage1
在subpackage2
内,这是不正确的。另外请注意,在python3中,永远不要使用隐式相对导入,因为它不再支持它,而应使用显式相对导入。
在每个文件夹中添加__init__.py
会将其转换为python软件包,您可以将其保留为空。您想用显式相对导入(如from subpackage1 import a
或绝对导入(如from ..subpackage1 import a
)替换from Project.subpackage1 import a
。这将是编写程序包的有效而正确的方法,您可以通过编写导入Project
并使用其子程序包和模块的脚本来对其进行测试。
但是,我假设您正在运行b.py
作为测试导入的主要模块。这意味着您正在运行如下命令行:python b.py
。像这样运行它,将为您提供一个模块搜索路径,该路径没有任何Project
之类的父路径。即使您的软件包在技术上没有错,这也会导致您不断收到ModuleNotFoundErrors。这就是为什么您需要一种sys.path.append(...
解决方法,该解决方法将您的父路径手动附加到模块搜索路径,以便将b.py
模块作为主要模块运行。如果这可以帮助您测试代码,则请务必使用它,但是可以使用绝对和显式相对导入,因为包中的模块应该以这种方式工作。
答案 1 :(得分:0)
首先,您需要在subpackage1中创建文件__init__.py
来声明它是一个模块
touch subpackage1/__init__.py
第二,您可以尝试在python3中进行相对导入
# b.py
from ..subpackage1 import a
或者您可以将当前目录添加到$PYTHONPATH
export PYTHONPATH=${PYTHONPATH}:${PWD}
答案 2 :(得分:0)
访问子包的一种方法是使用.
运算符,一直到最顶层的包或文件目录。因此,如果结构是
top_directory
|- package1
|- subpackage1
|- a.py
|- package2
|- subpackage2
|- b.py
然后您使用以下内容
#b.py
from top_directory.package1.subpackage1 import a
statements...
from
语句必须一直到达包含a.py
和b.py
的顶层目录。
答案 3 :(得分:0)
假设我们有以下文件和目录树:
$> tree
.
├── main.py
├── submodule1
│ ├── a.py
│ └── __init__.py
└── submodule2
├── b.py
└── __init__.py
2 directories, 5 files
因此,这里有一个示例,说明如何从a.py
到b.py
进行导入,反之亦然。
a.py
try:
# Works when we're at the top lovel and we call main.py
from submodule1 import b
except ImportError:
# If we're not in the top level
# And we're trying to call the file directly
import sys
# add the submodules to $PATH
# sys.path[0] is the current file's path
sys.path.append(sys.path[0] + '/..')
from submodule2 import b
def hello_from_a():
print('hello from a')
if __name__ == '__main__':
hello_from_a()
b.hello_from_b()
b.py
try:
from submodule1 import a
except ImportError:
import sys
sys.path.append(sys.path[0] + '/..')
from submodule1 import a
def hello_from_b():
print("hello from b")
if __name__ == '__main__':
hello_from_b()
a.hello_from_a()
然后, main.py :
from submodule1 import a
from submodule2 import b
def main():
print('hello from main')
a.hello_from_a()
b.hello_from_b()
if __name__ == '__main__':
main()
演示:
当我们处于最高级别时,我们试图致电main.py
$> pwd
/home/user/modules
$> python3 main.py
hello from main
hello from a
hello from b
当w在/ modules / submodule1级别时,我们正在尝试调用a.py
$> pwd
/home/user/modules/submodule1
$> python3 a.py
hello from a
hello from b
在/ modules / submodule2级别上,我们试图调用b.py
$> pwd
/home/user/modules/submodule2
$> python3 b.py
hello from b
hello from a