在以下代码中,无论执行a.py还是b.py,都会报错。
# a.py from b import y def x(): print('x') # b.py from a import x def y(): print('y') #在a.py中运行,产生的报错内容如下 Traceback (most recent call last): File "D:\python\a.py", line 1, in <module> from b import y File "D:\python\b.py", line 1, in <module> from a import x File "D:\python\a.py", line 1, in <module> from b import y ImportError: cannot import name 'y'
从报错提示中我们可以看出,a.py执行到"from b import y"时会跳转到b.py模块中,为了在b.py中找到y函数,解释器会自上而下的一行一行执行,当在b.py中执行到"from a import x"时又会跳转到a.py模块中进行搜索,如此循环反复,陷入死循环导致报错。
-----------------------------------------------------------------------------------------
我们尝试下对代码进行修改,将"from (模块) import (函数)" 改为"import (模块)",如下所示:
# a.py import b def x(): print('x') # b.py import a def y(): print('y')
结果发现,无论在a.py还是在b.py中运行,解释器都没有报错。而我若在a.py中运行,只需要b.y()便可正确访问b.py下的y函数。当我再进一步的做尝试,如下代码所示(在a.py中运行):
>>> b.y() y >>> b.a.b.a.b.a.b.a.b.a.b.a.b.y() y >>> x() x >>> b.a.x() x >>> b.a.b.a.b.a.b.a.b.a.x() x
可以看出,解释器都作出了正确的访问。
因此,不难得出结论:解释器对①"import (模块)"和②"from (模块) import (函数)"的解释方式是不同的。
以a.py做执行模块为例:
①的解释方式为:直接将b.py中的代码导入a.py中,并将来自b.py模块中的元素(包含函数、类、变量等)的名字前加上"b."以作为区分。
而②的解释方式为:前往b.py中寻找所需要导入的函数,而这个过程需要一行一行的找,遇到需要访问其他文件或模块的代码,就乖乖地去访问(可以理解为见缝就钻),拼命的找!疯狂的找!只有找到才肯罢休,否则会把指定的模块的代码一行一行的搜个遍。