【问题标题】:Solutions provided to solve circular dependency on python doesn't work为解决对 python 的循环依赖而提供的解决方案不起作用
【发布时间】:2019-09-29 08:07:25
【问题描述】:

我正在尝试处理对 python 的循环依赖(是的,它是必需的,因为我需要在不同的文件和模块上分离我的模型)。

我尝试了几种方法来解决这个问题(其中大部分已经由相关问题提出),但都没有解决问题。 注意:当移除循环依赖时,代码可以工作。

  1. 延迟导入

    /module_a/class_a.py

    from module_b.class_b import B
    
    class A:
        b = B()
    

    /module_b/class_b.py

    class B:
        from module_a.class_a import A
        a = A()
    
  2. 推迟两个导入

    /module_a/class_a.py

    class A:
        from module_b.class_b import B
        b = B()
    

    /module_b/class_b.py

    class B:
        from module_a.class_a import A
        a = A()
    
  3. 不使用 from .. 导入符号

    /module_a/class_a.py

    import module_b.class_b as mb
    
    class A:
        b = mb.B()
    

    /module_b/class_b.py

    import module_a.class_a as ma
    class B:
        a = ma.A()
    
  4. 不使用 from .. 导入符号和延迟导入

    /module_a/class_a.py

    class A:
        import module_b.class_b as mb
        b = mb.B()
    

    /module_b/class_b.py

    class B:
        import module_a.class_a as ma
        a = ma.A()
    

结果是所有解决方案都不起作用。我不知道这是否与调用在类定义上的事实有关,但它需要这样,因为我使用的是 ORM。

【问题讨论】:

  • 使用import ...还是from ... import ...无关紧要;两者都必须导入模块,而后者只是替换了导入后对a = module.a 之类的赋值的需要。究竟什么“不起作用”?
  • 我收到“ImportError: cannot import name 'A' from 'module_a.class_a'”或“AttributeError: module 'module_a.class_a' has no attribute 'A'
  • import 语句放在类中(以任何一种形式)都不会推迟它们。它们在执行 class 定义时发生。

标签: python python-import circular-dependency


【解决方案1】:

您尝试做的事情在 Python 中根本无法以这种方式完成。由于类定义相互依赖于另一个类的存在,因此没有另一个类就不能成功定义。即使在同一个文件中,这也会失败:

class A:
    b = B()
class B:
    a = A()

 NameError: name 'B' is not defined

循环依赖无论如何都被认为是result of a bad design,并且总是可以通过使用不同的类设计来避免。如果这会给您带来麻烦,请考虑询问有关如何重构的更具体的问题。

【讨论】:

  • 我明白了。在这种情况下,处理不同文件上模型之间的一对多关系的方法是什么?
  • @DouglasRamos 从this question 看来,您应该在“多”端的类中声明一个 ForeignKey,并可选择声明一个 related_name。然后 Django 处理能够通过集合访问“one”类中的“many”类的魔力,而无需您的“one”类显式引用它(因此不需要导入模块)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多