为什么导入模块会导致循环导入错误

时间:2020-07-15 14:55:03

标签: python python-3.x python-import python-module

我有这个用于我的项目布局:

projectFolder /
      setup/
         __init__.py
         setup.py
      Utils /
         __init__.py
         cloudmanager.py
startup.py

我正在尝试在Setup脚本(嵌套在另一个目录中)中导入cloudmanager.py模块。由于setup模块和Utils模块位于根目录中,因此我可以轻松地将它们startup.pycloudmanager.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

哪个给我的错误是

CREATE TABLE Files (
    Id INT PRIMARY KEY,
    [Name] NVARCHAR(100) NOT NULL,
    Size DECIMAL(18, 2) NOT NULL,
    ParentId INT NULL FOREIGN KEY REFERENCES Files(Id)
)

有帮助吗?那里有类似的问题,但是他们转向使用操作系统,我想避免...

2 个答案:

答案 0 :(得分:3)

好的,所以导入.. setup时出错了,确实是因为当父目录是一个包时,您不能进行相对导入。包是其中包含__init__.py文件的任何目录。

您可以通过执行以下两项操作之一来解决此问题:

  1. 您可以确保项目的根目录位于Python路径中,并将所有内容导入该根目录中。
  2. 您可以将项目的根目录本身设置为一个包,然后使用相对导入。

选项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突变后导入的每个文件中起作用)

选项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更常见。

答案 1 :(得分:0)

尝试使用:

import setup.setup