python3.x : 从父目录导入文件时出现 ModuleNotFoundError
python3.x : ModuleNotFoundError when import file from parent directory
我是 Python 的新手。这真的让我很困惑!
我的目录结构是这样的:
Project
| - subpackage1
|- a.py
| - subpackage2
|- b.py
| - c.py
当我使用 from subpackage1 import a
将 a.py
导入 b.py
时,我得到一个 ModuleNotFoundError。似乎我无法从父目录导入文件。
一些解决方案建议在每个目录中添加一个空文件__init__.py
,但这是行不通的。作为解决方法,我在每个子文件(即 a.py
和 b.py
)中添加了以下内容以访问父目录:
import os
import sys
sys.path.append(os.path.abspath('..'))
我试过在子文件中输出sys.path
,它只包括当前文件路径和anaconda路径,所以我必须将..
附加到sys.path
。
我该如何解决这个问题?有没有更有效的方法?
首先,您需要在 subpackage1 中创建文件 __init__.py
来声明它是一个模块
touch subpackage1/__init__.py
其次,您可以在python3
中尝试相对导入
# b.py
from ..subpackage1 import a
或者您可以将当前目录添加到 $PYTHONPATH
export PYTHONPATH=${PYTHONPATH}:${PWD}
访问子包的一种方法是使用 .
运算符一直到顶级包或文件目录。因此如果结构是
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
的顶级目录。
假设我们有这个文件和目录树:
$> tree
.
├── main.py
├── submodule1
│ ├── a.py
│ └── __init__.py
└── submodule2
├── b.py
└── __init__.py
2 directories, 5 files
所以,这是一个如何从 a.py
inti 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
当我们处于 /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
您遇到的第一个问题是由于 b.py
模块中的 from subpackage1 import a
行。
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
并使用其子包和模块的脚本来测试它。
但是,我假设您 运行ning b.py
作为主要模块来测试导入。这意味着您正在使用 运行ning 如下所示的命令行:python b.py
。 运行 它像这样给你一个模块搜索路径,它没有像 Project
这样的任何父路径。这将导致您不断收到 ModuleNotFoundErrors,即使您的包在技术上没有任何问题。这就是为什么您需要一个 sys.path.append(...
解决方法,手动将您的父路径附加到模块搜索路径,以便 运行 您的 b.py
模块作为主模块。如果这有助于您测试您的代码,那么一定要使用它,但是使用绝对和显式相对导入很好,因为包中的模块应该以这种方式工作。
我是 Python 的新手。这真的让我很困惑!
我的目录结构是这样的:
Project
| - subpackage1
|- a.py
| - subpackage2
|- b.py
| - c.py
当我使用 from subpackage1 import a
将 a.py
导入 b.py
时,我得到一个 ModuleNotFoundError。似乎我无法从父目录导入文件。
一些解决方案建议在每个目录中添加一个空文件__init__.py
,但这是行不通的。作为解决方法,我在每个子文件(即 a.py
和 b.py
)中添加了以下内容以访问父目录:
import os
import sys
sys.path.append(os.path.abspath('..'))
我试过在子文件中输出sys.path
,它只包括当前文件路径和anaconda路径,所以我必须将..
附加到sys.path
。
我该如何解决这个问题?有没有更有效的方法?
首先,您需要在 subpackage1 中创建文件 __init__.py
来声明它是一个模块
touch subpackage1/__init__.py
其次,您可以在python3
中尝试相对导入# b.py
from ..subpackage1 import a
或者您可以将当前目录添加到 $PYTHONPATH
export PYTHONPATH=${PYTHONPATH}:${PWD}
访问子包的一种方法是使用 .
运算符一直到顶级包或文件目录。因此如果结构是
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
的顶级目录。
假设我们有这个文件和目录树:
$> tree
.
├── main.py
├── submodule1
│ ├── a.py
│ └── __init__.py
└── submodule2
├── b.py
└── __init__.py
2 directories, 5 files
所以,这是一个如何从 a.py
inti 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
当我们处于 /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
您遇到的第一个问题是由于 b.py
模块中的 from subpackage1 import a
行。
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
并使用其子包和模块的脚本来测试它。
但是,我假设您 运行ning b.py
作为主要模块来测试导入。这意味着您正在使用 运行ning 如下所示的命令行:python b.py
。 运行 它像这样给你一个模块搜索路径,它没有像 Project
这样的任何父路径。这将导致您不断收到 ModuleNotFoundErrors,即使您的包在技术上没有任何问题。这就是为什么您需要一个 sys.path.append(...
解决方法,手动将您的父路径附加到模块搜索路径,以便 运行 您的 b.py
模块作为主模块。如果这有助于您测试您的代码,那么一定要使用它,但是使用绝对和显式相对导入很好,因为包中的模块应该以这种方式工作。