以下是我的代码。
main.py:
import moduleA
print('It works!')
moduleA.py:
import moduleB
def functionA():
return 0
moduleB.py:
import moduleA
globalVariableFromModuleB = moduleA.functionA()
如果我运行它,我会收到错误消息:
$ python main.py
Traceback (most recent call last):
File "main.py", line 3, in <module>
import moduleA
File "/home/asa/bugs/moduleA.py", line 3, in <module>
import moduleB
File "/home/asa/bugs/moduleB.py", line 8, in <module>
globalVariableFromModuleB_1 = functionB()
File "/home/asa/bugs/moduleB.py", line 6, in functionB
return moduleA.functionA()
Q1:在我的情况下,moduleB显式导入moduleA,因此我希望它可以工作,但事实并非如此。这是因为Python实现了进口并且没有两次进行吗?但是为什么它不能从内存中取出已经兑现的moduleA.functionA()而不是失败?我想当前的行为是一个错误。
Q2:如果我删除行“globalVariableFromModuleB = moduleA.functionA()”并只保留循环导入“import moduleA”,那么我没有失败。因此,Python中不禁止循环依赖。如果它们不能正常工作,那么它们允许的是什么,因为它显示了我的例子?
问题3:如果我将“import moduleA”更改为“from moduleA import functionA”,则主程序无法使用另一条消息“ImportError:无法导入名称functionA”失败。
另外,我想在这里发布针对那些不喜欢重新设计应用程序的人的解决方法,就像我的情况一样。
解决方法(仅通过实验找到)。要在main.py中的“import moduleA”之前添加“import moduleB”,即:
# main.py
import moduleB
import moduleA
print('It works!')
但是我必须在代码中的这个导入处留下长篇评论,因为main.py不直接使用来自moduleB的任何API,所以它看起来很难看。
有人可以建议一些更好的解决这种情况并回答上述3个问题吗?
答案 0 :(得分:2)
要解决这个问题,您只需要制动循环 - 在您的情况下,您可以放弃模块B中的导入ModuleA ,因为它不需要(您已经在主要导入A)
要真正了解正在发生的事情,请考虑以下事项:
你做导入,python会加载代码 并逐行执行它并将其添加到sys.modules中 知道它已经导入了
如果导入包含另一个import语句,python将加载并开始执行该代码,然后将模块名称添加到sys.module
希望这有帮助。
答案 1 :(得分:0)
例如,我会在这里发布更复杂的案例(当每个模块从全局上下文中的另一个模块调用一个函数时),该函数无需重新设计程序:
within
import moduleA
print('Value=%s' % moduleA.functionA())
globalVariableFromModuleA = 'globalA'
def functionA():
return globalVariableFromModuleA + '_functionA'
import moduleB
globalVariableFromModuleA = moduleB.functionB()
结果:
globalVariableFromModuleB = 'globalB'
def functionB():
return 'functionB'
import moduleA
globalVariableFromModuleB = moduleA.functionA()
该值不包含&#39; globalA&#39;这表明它有效,因为来自moduleA.py的globalVariableFromModuleA被moduleB.functionB()正确评估。
下一个例子表明,Python不仅可以导入模块,还可以防止无限递归,也可以用于函数调用。 如果我们通过以下方式修改moduleB.py:
$ python main.py
Value=functionB_functionA
结果:
globalVariableFromModuleB = 'globalB'
def functionB():
return globalVariableFromModuleB + '_functionB'
import moduleA
globalVariableFromModuleB = moduleA.functionA()
(在第二次进入functionA()时,它决定不再评估globalVariableFromModuleA,而是采用初始值&#39; globalA&#39;)