导入模块的Python作用域和名称空间

2024-03-29 14:48:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python中如何确定作用域和名称空间感到困惑。假设我有如下文件系统:

|-test1.py
 -test2.py

每个文件的定义如下:

测试1.py:

^{pr2}$

测试2.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的回答,我创建了一个Venn图来说明不同作用域之间的关系。假设解释器被第三个文件test3.py替换。它们的作用域如下:圆表示作用域,File test3表示test3.pyFile test2表示{},test2()表示test2.py中的函数{},test1()表示{}中的函数{}。test2()的作用域没有{},因此解释器将引用一个上层作用域{}。作用域File test2具有{},并调用它。在

enter image description here


Tags: 文件对象函数pyimport名称定义空间
1条回答
网友
1楼 · 发布于 2024-03-29 14:48:27

Python模块导入和全局命名空间管理是一个非常广泛的主题,因此我将把这个答案限制在您所看到的特定情况中。在

一般来说,Python是按顺序工作的。在

  1. 打开解释器,某些特殊值(如环境变量和其他内核变量)被注入到全局命名空间中。在
  2. 执行import test2,这将转到本地目录中的test2.py文件,并在相同的Python环境中执行该文件。在
  3. 在执行test2.py时,Python遇到了from test1 import test1。在
  4. 与步骤2类似,Python会找到test1.py,它会做一些额外的事情,因为您是在模块中导入一个函数,而不是导入模块本身,但是通常情况下,test1(函数)被放在当前范围内。在
  5. 您调用test2.test2(),因为在步骤2中导入了test2,所以它存在,test2.test2。因此,解释器跳转到test2.test2,并调用test1,因为它在名称空间中(我们刚刚在步骤3中导入了它),因此不会抛出任何错误,然后调用第二个print语句。在

在底层,事情显然要比这复杂一点,但这确实提供了Python如何处理这些事情的一般概述。在

相关问题 更多 >