带有模块导入的命名空间 [英] Namespaces with Module Imports
问题描述
尽管我已经学习Python大约一年了,但我正在学习Python并仍然是一个初学者.我正在尝试编写一个在主模块中调用的功能模块.被调用模块中的每个函数都需要math模块才能运行.我想知道是否有一种方法可以在不将数学模块导入被调用模块内部的情况下进行操作.这是我所拥有的:
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
并获取<function cool at 0x02B11AF0>
.因此,由于cool
在主模块的全局命名空间中,因此程序不应该首先在变量pi
的函数cool
内查找,然后在找不到的地方在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
换句话说,在module1
中的中,没有全局名称pi
,因为您尚未在其中导入它.在main.py
中执行from 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.
因此,如果要使用module1
中的pi
,则必须在module1.py
中执行from math import *
. (或者您可以找到其他方式注入它,例如,module1.py
可以执行from main import *
,或者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.)
作为旁注,您通常不希望在交互式解释器或偶尔在顶级脚本之外的任何地方执行from foo import *
.有一些例外情况(例如,一些模块明确设计为以这种方式使用),但是经验法则是import foo
或使用有限的from 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
.
这篇关于带有模块导入的命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!