为什么导入模块会导致循环导入错误
Why does importing modules result in a circular import error
我的项目布局是这样的:
projectFolder /
setup/
__init__.py
setup.py
Utils /
__init__.py
cloudmanager.py
startup.py
我正在尝试将 Setup
模块导入我的 cloudmanager.py
脚本(嵌套在另一个目录中)。我可以轻松地在我的 startup.py
脚本中导入 setup
模块和 Utils
模块,因为它位于根目录中。
我试过了(在我的 cloudmanager.py
脚本中):
from . import setup
这给我的错误是:
ImportError: cannot import name 'setup' from partially initialized module 'Utils' (most likely due to a circular import)
我试过了:
from .. import setup
这给我的错误是:
ValueError: attempted relative import beyond top-level package
有什么帮助吗?那里有这样的问题,但他们转向使用 OS,我想避免...
尝试使用:
import setup.setup
好的,所以你在导入 .. setup
时出错的原因确实是当父目录是一个包时你不能进行相对导入。包是其中包含 __init__.py
文件的任何目录。
您可以通过执行以下两项操作之一来解决此问题:
- 您可以确保项目的 根目录 位于 Python 路径中并导入根目录中的所有内容。
- 您可以将项目的根目录本身作为一个包,然后使用相对导入。
选项 1:从项目根目录导入
如果您的 projectFolder
文件夹位于 /home/you/projects/projectFolder
,确保 您的 PYTHONPATH
中有 /home/you/projects/projectFolder
。例如,当您 运行 您的主脚本时,您可以预先设置它。在bash中(假设是Unix环境):
export PYTHONPATH=/home/you/projects/projectFolder
python /home/you/projects/projectFolder/startup.py
如果你想避免改变外部环境,你也可以在 startup.py 内部这样做:
# startup.py
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__)))
如果您在 startup.py 中这样做,startup.py 的目录将始终位于 Python 路径中。
一旦您其中之一,您就可以将所有导入都基于项目的相对位置。例如:
import setup.setup
import Utils.cloudmanager
(这将在 sys.path
突变 运行s 之后导入的每个文件中起作用)
选项 2:相对导入
如果您将项目的根设为 Python 包,则可以完全使用相对导入。例如,您将拥有这些文件:
projectFolder/__init__.py
projectFOlder/setup/__init__.py
projectFolder/setup/setup.py
projectFolder/Utils/__init__.py
projectFolder/Utils/cloudmanager.py
如果你这样做,在 cloudmanager.py
内,你可以 运行 from .. import setup
就好了。
你是做什么的?
这两个都是有效的选项。一般来说,相对导入的歧义较少,因为它们避免了名称冲突,但它们是 Python 的较新功能,因此选项 #1 通常更常见。
我的项目布局是这样的:
projectFolder /
setup/
__init__.py
setup.py
Utils /
__init__.py
cloudmanager.py
startup.py
我正在尝试将 Setup
模块导入我的 cloudmanager.py
脚本(嵌套在另一个目录中)。我可以轻松地在我的 startup.py
脚本中导入 setup
模块和 Utils
模块,因为它位于根目录中。
我试过了(在我的 cloudmanager.py
脚本中):
from . import setup
这给我的错误是:
ImportError: cannot import name 'setup' from partially initialized module 'Utils' (most likely due to a circular import)
我试过了:
from .. import setup
这给我的错误是:
ValueError: attempted relative import beyond top-level package
有什么帮助吗?那里有这样的问题,但他们转向使用 OS,我想避免...
尝试使用:
import setup.setup
好的,所以你在导入 .. setup
时出错的原因确实是当父目录是一个包时你不能进行相对导入。包是其中包含 __init__.py
文件的任何目录。
您可以通过执行以下两项操作之一来解决此问题:
- 您可以确保项目的 根目录 位于 Python 路径中并导入根目录中的所有内容。
- 您可以将项目的根目录本身作为一个包,然后使用相对导入。
选项 1:从项目根目录导入
如果您的 projectFolder
文件夹位于 /home/you/projects/projectFolder
,确保 您的 PYTHONPATH
中有 /home/you/projects/projectFolder
。例如,当您 运行 您的主脚本时,您可以预先设置它。在bash中(假设是Unix环境):
export PYTHONPATH=/home/you/projects/projectFolder
python /home/you/projects/projectFolder/startup.py
如果你想避免改变外部环境,你也可以在 startup.py 内部这样做:
# startup.py
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__)))
如果您在 startup.py 中这样做,startup.py 的目录将始终位于 Python 路径中。
一旦您其中之一,您就可以将所有导入都基于项目的相对位置。例如:
import setup.setup
import Utils.cloudmanager
(这将在 sys.path
突变 运行s 之后导入的每个文件中起作用)
选项 2:相对导入
如果您将项目的根设为 Python 包,则可以完全使用相对导入。例如,您将拥有这些文件:
projectFolder/__init__.py
projectFOlder/setup/__init__.py
projectFolder/setup/setup.py
projectFolder/Utils/__init__.py
projectFolder/Utils/cloudmanager.py
如果你这样做,在 cloudmanager.py
内,你可以 运行 from .. import setup
就好了。
你是做什么的?
这两个都是有效的选项。一般来说,相对导入的歧义较少,因为它们避免了名称冲突,但它们是 Python 的较新功能,因此选项 #1 通常更常见。