【问题标题】:Circular import error while organising __init__.py files组织 __init__.py 文件时出现循环导入错误
【发布时间】:2016-03-04 19:34:23
【问题描述】:

我正在将一系列 python 文件放入他们自己的模块中。因此,我将它们放在一个目录中并添加了一个 init 文件。

为了让我能够按如下方式访问它们

from module import subclass

而不是

from module.submodule import subclass

我正在尝试将我想要公开的所有类导入到 init 文件中。然而,由于许多子模块相互引用(它是一个 Django 项目,所以所有类都是相互的外键),当我运行代码时,我很快就会遇到循环导入。

是否有正确的方法来组织 init.py 文件以避免这种情况发生?

例如:

  File "/Users/.../models/__init__.py", line 4, in <module>
from Guests import Guest
  File "/Users/.../models/Guests.py", line 5, in <module>
from Logs import LogEntry
  File "/Users/..../models/Logs.py", line 6, in <module>
from Staff import Staff
  File "/Users/.../Staff.py", line 5, in <module>
from Properties... import Site
  File "/Users/./Properties.py", line 7, in <module>
from Guests import Guest
ImportError: cannot import name Guest

【问题讨论】:

    标签: python django import


    【解决方案1】:

    如果 A 依赖于 X 并且 X 依赖于 A 可能他们认为生活在同一个单元中,最好检查并将循环依赖拆分到同一个模块中,然后寻找解决方法。

    不推荐:但是,如果您无法调整包的结构,您可以将循环导入移动到函数定义中或遵循该原则(我不知道您的代码...)。

    如果类 A.py 依赖于 B.py 而 B.py 依赖于 A.py:

    # B.py
    class B:
    
      def __init__(self):
            import A 
            A.some_method()
    

    更新:正如 cmets 中指出的那样,Django 外键变量会导致循环导入以避免该问题删除类的导入并改用模型名称作为字符串。

    item = models.ForeignKey('class_file.Item')
    

    【讨论】:

    • 问题是有一个日志模型可以记录所有其他 Django 模型中的更改,以便将所有内容联系在一起,但是代码的长度为 O(3k) 行,这有点无法管理。与其说它们直接相互依赖,不如说是 A 调用 B,但 B 是 A 的外键。
    • 我也不能在函数定义中“隐藏”导入,因为 Django 外键是类变量。
    • 使用完整评论,我又调整了答案。
    • 啊,我不知道你可以将路径作为字符串传递给外键,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2014-05-21
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多