当前位置: 首页 > 面试题库 >

具有模块导入的命名空间

狄玮
2023-03-14
问题内容

尽管我已经学习Python大约一年了,但我正在学习Python并仍然是一个初学者。我正在尝试编写一个在主模块中调用的功能模块。被调用模块中的每个函数都需要math模块才能运行。我想知道是否有一种方法可以在不将数学模块导入被调用模块内部的情况下进行操作。这是我所拥有的:

main.py

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()

module1.py

def cool():

    print pi

运行时,main.py我得到:

3.14159265359

Traceback (most recent call last):
  File "Z:\Python\main.py", line 10, in <module>
    module1.cool()
  File "Z:\Python\module1.py", line 3, in cool
    print pi
NameError: global name 'pi' is not defined

我很难理解的是为什么在运行时出现名称错误main.py。我知道该变量pi在导入时对主模块变为全局,因为wow可以访问它。我也知道,cool导入后对主模块来说是全局的,因为我可以打印module1.cool并获取<function cool at 0x02B11AF0>。因此,既然cool位于主模块的全局命名空间中,程序是否不应该首先cool在变量的函数内部查找pi,然后在找不到该函数的情况下,在main模块内部查找该变量pi
那里 找到它

解决这个问题的唯一方法是在其中导入数学模块module1.py。我不喜欢这样的想法,尽管因为它会使事情变得更复杂,并且我喜欢漂亮,简单的代码。我觉得我即将掌握名称空间,但是在这方面需要帮助。谢谢。


问题答案:

如回溯所示,问题不在main.py,而是在module1.py

Traceback (most recent call last):
  File "Z:\Python\main.py", line 10, in <module>
    module1.cool()
  File "Z:\Python\module1.py", line 3, in cool
    print pi
NameError: global name 'pi' is not defined

换句话说, 在中module1,没有全局名称pi,因为您尚未将其导入。当您from math import *在中执行操作时main.py,这只是将所有内容从math模块的命名空间导入main模块的命名空间,而不是导入 每个 模块的命名空间。

我认为您在这里缺少的关键是每个模块都有自己的“全局”名称空间。刚开始时这可能有点令人困惑,因为在像C这样的语言中,所有extern变量和函数都共享一个全局名称空间。但是一旦您克服了这个假设,Python的方式就很有意义了。

因此,如果要使用pifrom module1,则必须执行from math import *in
module1.py。(或者,您可以找到其他方式注入它,例如,module1.py可以做from main import *,或者main.py可以做module1.pi = pi等。或者您可以塞入pi魔术builtins/__builtin__模块中,或者使用各种其他技巧。但是显而易见的解决方案是import在您所需要的地方进行操作。想要导入。)

附带一提,您通常不希望from foo import *在交互式解释器或顶级脚本之外的任何地方做任何事情。有例外(例如,一些模块被明确设计为以这种方式使用),但是经验法则是要么import foo使用要么使用limited from foo import bar, baz



 类似资料:
  • 问题内容: 我开始金字塔式保护区时会得到以下堆栈跟踪: 从python REPL可以正常工作: 并从命令行导入: 删节的输出显示了我正在使用的内容: My设置为该树的根: 我在使用python 2.7的virtualenv中运行它。今天我一直在进行此工作,但我不知道问题出在哪里。一方面,对于之前出现的 一些 导入似乎还可以: __ (我将最后一行更改为绝对导入。不走运。) 我尝试过的事情: 重建v

  • 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变化。 “内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,这是为了与ECMAScript 2015里的术语保持一致,(也就是说 module X { 相当于现在推荐的写法 namespace X {)。 这篇文章将概括介绍在TypeScript里使用模块与命名空间来组织代码的方法。 我们也会谈及

  • 关于术语的一点说明: 请务必注意一点,TypeScript 1.5里术语名已经发生了变化。 “内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,这是为了与ECMAScript 2015里的术语保持一致,(也就是说 module X { 相当于现在推荐的写法 namespace X {)。 介绍 这篇文章将概括介绍在TypeScript里使用模块与命名空间来组织代码的方法。 我们也

  • 导入PyPDF2时出错(没有名为的模块)。我尝试安装Python版本。2、也不工作。我想这个问题可能和安装模块的路径有关,但我无法更改它。。。或者使用Python版本,因为文档中提到了3.2-3.5版 https://pythonhosted.org/PyPDF2/AboutPyPDF2。html 指令 C:\Users\Xiaomi C:\Users\Xiaomi 导入PyPDF2 Module

  • 我试图通过定义类似java的包、类和导入的语法来学习Xtext。我的语法片段看起来像这样,CompilationUnit是根对象。 为了导入交叉引用,我使用DefaultGlobalScopeProvider,我已经用我自己的版本重写了QualifiedNameProvider,该版本附加了包名作为topClass的QualifiedName的前缀。为了自动导入自己的包,我编辑了特定于项目的Sco

  • 我需要一个简单的xslt,它接受输入并提供如下所述的输出。我已经编写了xslt,但名称空间被忽略了。你能帮我一下吗。 输入消息: 预期输出消息: 实际输出消息: XSLT: