Python:具有模块导入的命名空间 [英] Python: Namespaces with Module Imports
问题描述
我正在学习Python并且仍然是初学者,尽管我已经研究了大约一年了。我正在尝试编写一个在主模块中调用的函数模块。被调用模块中的每个函数都需要运行数学模块。我想知道是否有办法在没有导入被调用模块内的数学模块的情况下这样做。这是我有的:
I am learning Python and am still a beginner, although I have been studying it for about a year now. I am trying to write a module of functions which is called within a main module. Each of the functions in the called module needs the math module to run. I am wondering if there is a way to do this without importing the math module inside the called module. Here is what I have:
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
并获得<功能很酷,在0x02B11AF0>
。所以,因为 cool
在主模块的全局命名空间内,所以程序不应该首先查看函数 cool
对于变量 pi
,然后当它找不到它时,在 main
模块中查找变量 pi
和在那里找到?
What I'm having a hard time understanding is why I get a name error when running main.py
. I know that the variable pi
becomes global to the main module upon import because wow
can access it. I also know that cool
becomes global to the main module upon import because I can print module1.cool
and get <function cool at 0x02B11AF0>
. So since cool
is inside the global namespace of the main module, shouldn't the program first look inside the function cool
for the variable pi
, and then when it doesn't find it there, look inside main
module for the variable pi
and find it there?
解决这个问题的唯一方法我知道是在 module1.py
中导入数学模块。我不喜欢这个想法,但是因为它使事情变得更复杂,而且我喜欢漂亮,简单的代码。我觉得我已经接近掌握命名空间,但需要帮助。谢谢。
The only way to get around this that I know of is to import the math module inside module1.py
. I don't like the idea of that, though because it makes things more complicated and I am a fan of nice, simple code. I feel like I am close to grasping namespaces, but need help on this one. Thanks.
推荐答案
正如追溯所示,问题不在 main.py
,但在 module1.py
:
As the traceback shows, the problem isn't in main.py
, but in 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
换句话说, in module1
,没有全局名称 pi
,因为你没有在那里导入它。当您从 main.py
中的math import * 执行时,只需从
导入所有内容math
模块的命名空间到 main
模块的命名空间,而不是每个模块的命名空间。
In other words, in module1
, there is no global name pi
, because you haven't imported it there. When you do from math import *
in main.py
, that just imports everything from the math
module's namespace into the main
module's namespace, not into every module's namespace.
我认为你在这里缺少的关键是每个模块都有自己的全局命名空间。起初这可能有点令人困惑,因为在像C这样的语言中,所有 extern
变量和函数共享一个全局命名空间。但是一旦你超越了这个假设,Python的方式就会很有意义。
I think the key thing you're missing here is that each module has its own "global" namespace. This can be a bit confusing at first, because in languages like C, there's a single global namespace shared by all extern
variables and functions. But once you get past that assumption, the Python way makes perfect sense.
所以,如果你想使用 pi
从 module1
,您必须在 module1.py <中从math import *
执行 / code>。 (或者你可以找到一些其他方式来注入它 - 例如,
进行 module1.py
可以从主导入或者
main.py
可以做 module1.pi = pi
等等。或者你可以补充 pi
进入神奇的 builtins
/ __ builtin __
模块,或者使用其他各种技巧。但是显而易见的解决方案是在你想要导入的地方进行 import
。)
So, if you want to use pi
from module1
, you have to do the from math import *
in module1.py
. (Or you could find some other way to inject it—for example, module1.py
could do from main import *
, or main.py
could do module1.pi = pi
, etc. Or you could cram pi
into the magic builtins
/__builtin__
module, or use various other tricks. But the obvious solution is to do the import
where you want it imported.)
作为旁注,除了交互式解释器或偶尔的顶级脚本之外,您通常不希望从foo import * 执行。有一些例外(例如,一些模块明确设计为以这种方式使用),但经验法则是
import foo
或使用有限的来自foo import bar,baz
。
As a side note, you usually don't want to do from foo import *
anywhere except the interactive interpreter or, occasionally, the top-level script. There are exceptions (e.g., a few modules are explicitly designed to be used that way), but the rule of thumb is to either import foo
or use a limited from foo import bar, baz
.
这篇关于Python:具有模块导入的命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!