python ImportError: cannot import name ‘ ××ב解决方法

初次接触python,经常踩坑,因为很多低级错误导致程序BUG,结果调了好长时间才找到问题所在,这次来分享一下Python模块导入过程中新手很容易出现的一个问题,并对规避该问题的手段进行简单总结。

问题表现:
程序编译运行时产生错误,提示信息为:
python ImportError: cannot import name ’ ×××’
产生错误的语句发生在模块导入语句中,比如:
from A import a
产生的错误提醒为:
python ImportError: cannot import name ’ a’

问题分析
经过将近一天的流程跟踪(不要问我为什么这么长时间,只怪他程序写的太垃圾>_<)发现问题出现在同一个模块在相同的导入语句下被重复调用,也就是“循环引用”,在第一次调用该模块时一切正常,而在第二次调用该模块时便发生错误。

为便于说明问题,我此处大致简化一下程序的结构。

假设程序执行的入口文件写法如下:

from A import a
from B import b
form C import c

Program()

def ProgramInit():
     ……

此处简单解释一下,"from A import a"当中的A代表模块(即.py文件)名称,a代表A模块当中对象(可以是class,也可以是该模块当中的全局变量)的名称。
程序在执行此模块时,并不是直接从模块当中的语句Program()当中开始执行的,而是首先自上而下执行导入语句。当程序执行导入语句“from A import a”时,会进入模块A,假设模块A当中的执行语句如下:

from AA1 import aa1
from AA2 import aa2
from AA3 import aa3

程序将自自上而下执行,分别导入aa1,aa2,aa3,假设AA1当中的存在这样一条导入语句:

 from A import a

当程序运行到此处时便会报错,因为此处发生了循环
python ImportError: cannot import name ‘ ××ב解决方法_第1张图片
如果继续进行,那么程序将在这个循环中无止境地运行下去,因此程序会在此处报错,如果大家出现同样的问题,单步跟调用过程,看看会不会在同一个调用语句当中多次执行到相同的模块上,如果是,那么是循环引用问题无疑了

规避方法
出现这样的问题是由于模块间调用关系的不合理设计产生的,防止这种问题的一种有效手段便是明确的模块分级设计,我们假设当前的模块目录如下图所示

python ImportError: cannot import name ‘ ××ב解决方法_第2张图片
A,AA1,AAA1三个模块分别属于不同层级,每个模块都有自己的_ini_函数,并在其中完成子模块的导入。如果在高层级的模块当中导入底层级的模块(比如在AAA1中导入A),则发生上述循环引用问题的风险将会大大增加。但模块分层由不可避免,为防止这种情况出现,我们在为模块设计导入程序时,应当将模块的分层结构考虑进去,可以规定:
1.正常情况下,只能导入相同层级且处于同一目录下的同级别模块(如AA1只能导入AA2,或AA3)
2.如果跨层级导入过程必须发生,则方向必须为自高向低,严禁高层级模块导入底层级模块(只能A导入AA1,而不能AA1导入A),且跨层级的程度只能小于或等于1

以上便是个人的经验和思考,如有不足之处欢迎指正,最后祝各位IT同行早日脱坑

你可能感兴趣的:(python,python)