【问题标题】:How does importing a function from a module work in Python?在 Python 中如何从模块中导入函数?
【发布时间】:2017-01-05 08:19:39
【问题描述】:

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

def testf():
    print(os.listdir())

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

import os
from some_module import testf

testf()

但是执行 test.py 给了我NameError: name 'os' is not defined。我已经在test.py 中导入了os,而testftest.py 的命名空间中。那么为什么会出现这个错误呢?

【问题讨论】:

    标签: python python-3.x module python-import


    【解决方案1】:

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

    Python 中的 import 语句读取正在导入的文件的内容并在其自己的单独上下文中对其进行评估 - 因此,在您的示例中,some_module.py 中的代码无法访问或了解其中存在的任何内容test.py 或任何其他文件。可以这么说,它以“白板”开始。如果some_module.py的代码要访问os模块,则必须在some_module.py的顶部导入。

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

    import some_module
    

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

    import os
    

    some_module.py,然后这将创建一个名为os 的模块属性,您的代码将找到它需要的内容。

    您可能还对我写的其他一些答案感兴趣,这些答案可能有助于您理解 Python 的 import 声明:

    【讨论】:

      【解决方案2】:

      名称testf 位于test 的命名空间中。 testf 函数的内容仍在some_module 中,无法访问test 中的任何内容。

      如果您有需要模块的代码,则需要将该模块导入该代码所在的同一文件中。导入一个模块只会将它导入到您导入它的一个文件中。 (同一模块在不同文件中的多次导入不会导致显着的性能损失;模块的实际加载只发生一次,稍后对同一模块的导入只会获得对已导入模块的引用。)

      【讨论】:

        【解决方案3】:

        导入模块会将其名称添加为 current 范围的属性。由于不同的模块有独立的作用域,some_module 中的任何代码都不能在没有先导入的情况下使用__main__(执行的脚本)中的名称。

        【讨论】:

          猜你喜欢
          • 2015-03-05
          • 2022-11-11
          • 2017-11-22
          • 1970-01-01
          • 2016-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-14
          相关资源
          最近更新 更多