最好的做法是能不弄,就不要弄循环import,像go这种语言就由编译器禁止你这么搞,搞了就编译错误
py中循环import存在的问题主要在于对于没有导入的模块,import本身就是一次执行,就是把模块代码的global域当成正常代码执行一次,这样如果多个模块的全局变量有循环依赖,就可能异常,比如:
A.py:
import B
a = B.a
B.py:
import A
print A.a
a = 123
无论先import谁,都会报它没有属性a,这里import,赋值,print都是py的语句,一条条执行
比如从main.py里面先import A:
1 首次导入,A先进入sys模块的module表
2 由于是首次导入,从A开始执行,执行import B这句
3 B首次导入,进入sys的module表
4 从B.py的第一句开始,执行import A这句,由于A已经在表中,略过,然后执行print A.a,这时候A.py还没执行到给a赋值的地方,所以异常
避免这种情况一般就没什么事了,个人一个习惯和建议是,全局变量初值都赋值为不依赖其他模块的值,比如None,整数等,如果需要依赖,模块提供init函数,由main模块在程序启动时候手工按顺序初始化好
需要注意的是,和import是可执行语句一样,def和class对于py都是可执行语句,def是把其下的代码块对应的函数对象关联给函数名,等于一个赋值,class要更复杂一点,先把它下面的代码块当成一个普通函数执行,最后执行MAKE_CLASS字节码做convert再赋值给类名,其他的,修饰器也是可执行代码,对py来说,一切都是指令,唯一一个“声明”语法,是global