如何修复导入的循环依赖项

wro*_*ame 0 python import circular-dependency python-3.x

我有三个文件:

testimports模块:

#import moduleTwo
import moduleOne

hiString = "Hi!"

moduleOne.sayHi()
Run Code Online (Sandbox Code Playgroud)

ModuleOne的:

import moduleTwo

class sayHi():
    moduleTwo.printHi()
Run Code Online (Sandbox Code Playgroud)

ModuleTWO中:

import testimports

def printHi():
    print(testimports.hiString)
Run Code Online (Sandbox Code Playgroud)

如果我跑testimports,我得到:

Traceback (most recent call last):
  File "..file path snipped../testimports/src/testimports.py", line 2, in <module>
    import moduleOne
  File "..file path snipped../testimports/src/moduleOne.py", line 1, in <module>
    import moduleTwo
  File "..file path snipped../testimports/src/moduleTwo.py", line 1, in <module>
    import testimports
  File "..file path snipped../testimports/src/testimports.py", line 6, in <module>
    moduleOne.sayHi()
AttributeError: 'module' object has no attribute 'sayHi'
Run Code Online (Sandbox Code Playgroud)

但是,如果我取消注释该import moduleTwotestimports,程序会在它停止工作之前到达这一点:

Traceback (most recent call last):
  File "..file path snipped../testimports/src/testimports.py", line 1, in <module>
    import moduleTwo
  File "..file path snipped../testimports/src/moduleTwo.py", line 1, in <module>
    import testimports
  File "..file path snipped../testimports/src/testimports.py", line 2, in <module>
    import moduleOne
  File "..file path snipped../testimports/src/moduleOne.py", line 3, in <module>
    class sayHi():
  File "..file path snipped../testimports/src/moduleOne.py", line 4, in sayHi
    moduleTwo.printHi()
AttributeError: 'module' object has no attribute 'printHi'
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个循环依赖问题呢?

Muh*_*uri 9

verisimilidude是正确的方向.我会扩展一点,以提供更多细节.

在这两种情况下,都会发生这种情况:

  1. testimports 被执行为 __main__
  2. testimports进口moduleOne.现在moduleOne从文件中读取并添加到导入模块列表中sys.modules.
  3. moduleOne通过导入执行导入的导入moduleTwo.现在moduleTwo从文件中读取并添加到导入模块列表中sys.modules.请注意,在此阶段其余部分moduleOne尚未执行,因此sayHi未定义.
  4. 现在moduleTwo通过导入开始执行testimports.这是第一次testimports导入,它与它无关__main__.它现在插入sys.modules.
  5. 这是事情变得有趣的地方.新进口的testimports进口产品moduleOne.moduleOne已经存在sys.modules,所以不再读了.然后执行进行到该行moduleOne.sayHi().但是导入moduleOne还没有完成,sayHi还没有定义.因此我们得到错误.

如果moduleTwo取消注释,则会发生类似的循环.从本质上说,__main__进口moduleTwo其进口testimports其通过进口moduleTwo这已经是进口和出口moduleOne; 然后导入moduleTwo然后尝试调用moduleTwo.printHi哪个尚未定义,因为moduleTwo还没有完成执行.

Anatoly Rr的解决方案通过使testimports模块在导入时不调用任何其他模块功能来解决所有这些问题.因此当它被导入时它moduleTwo不会调用moduleOne.sayHi.只有在启动时__main__才会执行,以便在所有导入后执行被延迟.

这个故事的主旨?如果可能,请避免Python中的循环依赖.