关于python中模块的环状引用(circular imports)

从stackoverflow上面copy过来的

1、

Imports are pretty straightforward really. Just remember the following:

'import' and 'from xxx import yyy' are executable statements. They execute when the running program reaches that line.

If a module is not in sys.modules, then an import creates the new module entry in sys.modules and then executes the code in the module. It does not return control to the calling module until the execution has completed.

If a module does exist in sys.modules then an import simply returns that module whether or not it has completed executing. That is the reason why cyclic imports may return modules which appear to be partly empty.

Finally, the executing script runs in a module named __main__, importing the script under its own name will create a new module unrelated to __main__.

Take that lot together and you shouldn't get any surprises when importing modules.


‘import’和‘from xxx import yyy' 是可执行语句,每当程序运行到他们所在的哪一行他们就执行,如果import的模块在sys.modules中未找到,import语句就在sys.modules中会创建一个新的模块,此时这个模块就已经存在于sys.modules中了,但是他的__dict__还是空的,紧接着会执行这个模块中的语句,以填充他的__dict__,直到这个模块执行结束,才会返回到刚才的import语句继续执行;如果import的模块sys.modules中已经存在,那么import语句将会直接返回这个模块而不论他是否已经执行完毕,这就是为什么cyclic imports返回的模块有时候会是空的


最后,执行脚本在命名为__main__的模块中运行,导入一个模块将会在sys.modules中创建一个以自己名称命名的和__main__模块无关的模块


2、

If you do import foo inside bar and import bar inside foo, it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.

The problem is when instead you do from foo import abc and from bar import xyz. Because now each module requires the other module to already be compiled (so that the name we are importing exists) before it can be compiled.

当你在bar模块中执行import foo,同时在foo模块中执行import bar,执行不会出现问题,直到两个模块中需要依赖彼此的程序执行时,两个模块才会完全加载,而且拥有指向彼此的引用

当你在bar模块中执行from foo import abc,同时在foo模块中执行from bar import xyz,问题出现了。因为这种情况下两个模块互相之间需要另一个模块完全编译完成,只有这样,我们才能从另外一个模块中找到我们需要import的名称,但是很明显这个时候我们的程序很难完全编译完成,除非我们至少其中的一个from ... import ...出现在最后一行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章