带有模块导入的命名空间 [英] Namespaces with Module Imports

查看:98
本文介绍了带有模块导入的命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管我已经学习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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆