小编典典

具有模块导入的命名空间

python

尽管我已经学习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。我不喜欢这样的想法,尽管因为它会使事情变得更复杂,并且我喜欢漂亮,简单的代码。我觉得我即将掌握名称空间,但是在这方面需要帮助。谢谢。


阅读 180

收藏
2020-12-20

共1个答案

小编典典

如回溯所示,问题不在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

2020-12-20