我对如何在Python中确定范围和名称空间感到困惑。假设我的文件系统如下:
|-test1.py
-test2.py
每个文件的定义如下:
test1.py:
#!/usr/bin/python
def test1():
print('test1')
test2.py:
#!/usr/bin/python
from test1 import test1
def test2():
test1()
print('test2')
在python交互式解释器中,如果执行以下操作:
import test2
test2.test2()
,代码可以正常运行并给出以下结果:
test1
test2
从输出中,我们可以看到解释器可以正确识别test1()函数对象。在执行过程中导入test1.test1时,我感到困惑的是?该对象何时进入全球范围?
基于@Ziyad Edher的答案,我创建了一个维恩图来说明不同作用域之间的关系。假设解释器被第三个文件test3.py代替。它们的范围如下:圆圈代表范围,File test3
指test3.py
,File test2
指test2.py
,test2()
指功能{ test2()
中的{1}},test2.py
指test1()
中的功能test1()
。 test1.py
的范围没有test2()
,因此解释器将引用上级范围test1()
。范围File test2
具有File test2
,并对其进行调用。
答案 0 :(得分:1)
Python模块导入和全局名称空间管理是一个非常广泛的主题,因此,我将把这个答案限于您所看到的特定情况。
通常,Python的工作顺序非常顺畅。
import test2
,这将转到本地目录中的test2.py
文件,并在相同的Python环境中执行该文件。test2.py
时,Python遇到了from test1 import test1
。test1.py
,它做了一些额外的事情,因为您是在模块中而不是模块本身中导入一个函数,但是通常来说,{{1} }(该函数)被置于当前作用域中。test1
,因为test2.test2()
已在步骤2中导入,所以它存在,test2
也是如此。因此,解释器跳至test2.test2
并被调用test2.test2
,由于它在名称空间中(我们在步骤3中刚刚导入了它),没有抛出错误,因此调用了第二个print语句。在底层,事情显然比这要复杂一些,但这确实提供了Python如何处理这些东西的一般概述。