从模块导入函数在 Python 中如何工作?

Tra*_*net 2 python module python-import python-3.x

我有一个some_module.py包含以下代码的模块:

def testf():
    print(os.listdir())
Run Code Online (Sandbox Code Playgroud)

现在,在一个名为 的文件中test.py,我有以下代码:

import os
from some_module import testf

testf()
Run Code Online (Sandbox Code Playgroud)

但是执行 test.py 给了我NameError: name 'os' is not defined. 我已经导入ostest.py,并且testftest.py. 那么为什么会出现这个错误呢?

Dav*_*d Z 5

import与包含文件的内容不同,就像您直接键入它来代替import语句一样。如果您来自 C 背景,您可能会认为它以这种方式工作,其中#include预处理器指令执行此操作,但 Python 不同。

importPython中的语句读取导入的文件的内容和评估在其独立的上下文-因此,在你的榜样,在代码中some_module.py有没有访问或任何存在于知识test.py或任何其他文件。可以这么说,它以“空白石板”开始。如果some_module.py的代码要访问该os模块,则必须在some_module.py.

当一个模块在 Python 中导入时,它就变成了一个object。也就是说,当你写

import some_module
Run Code Online (Sandbox Code Playgroud)

Python 做的第一件事就是创建一个新的类型对象module来表示正在导入的模块。当解释器遍历 中的代码时some_module.py,它将在该文件中定义的任何变量、函数、类等分配为这个新模块对象的属性。因此,在您的示例中,模块对象将具有一个属性testf. 当函数中的代码testf想要访问该变量时os,它会查看函数本身(本地范围)并看到os那里没有定义,因此它会查看testf属于的模块对象的属性(这是“全局范围”) " 范围,尽管它不是真正的全球性)。在您的示例中,它不会os在那里看到,因此您会收到错误消息。如果添加

import os
Run Code Online (Sandbox Code Playgroud)

to some_module.py,然后将在 name 下创建模块的属性os,您的代码将找到它需要的内容。

您可能还对我写的其他一些可以帮助您理解 Pythonimport语句的答案感兴趣: