Python 具有模块导入的名称空间

Python 具有模块导入的名称空间,python,import,module,namespaces,local,Python,Import,Module,Namespaces,Local,我正在学习Python,虽然我已经学习了大约一年,但我仍然是一名初学者。我试图编写一个在主模块中调用的函数模块。被调用模块中的每个函数都需要数学模块来运行。我想知道是否有一种方法可以做到这一点,而无需在被调用的模块中导入数学模块。以下是我所拥有的: main.py: from math import * import module1 def wow(): print pi wow() module1.cool() def cool(): print pi Trace

我正在学习Python,虽然我已经学习了大约一年,但我仍然是一名初学者。我试图编写一个在主模块中调用的函数模块。被调用模块中的每个函数都需要数学模块来运行。我想知道是否有一种方法可以做到这一点,而无需在被调用的模块中导入数学模块。以下是我所拥有的:

main.py

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()
def cool():

    print pi
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
import module1

def wow():
    print module1.pi

wow()
module1.cool()
from math import pi

def cool():
    print pi
module1.py

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()
def cool():

    print pi
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
import module1

def wow():
    print module1.pi

wow()
module1.cool()
from math import pi

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
3.14159265359
回溯(最近一次呼叫最后一次):
文件“Z:\Python\main.py”,第10行,在
模块1.cool()
文件“Z:\Python\module1.py”,第3行,冷却
打印圆周率
NameError:未定义全局名称“pi”
我很难理解为什么在运行
main.py
时会出现名称错误。我知道变量
pi
在导入时会成为主模块的全局变量,因为
wow
可以访问它。我还知道,
cool
在导入时对主模块是全局的,因为我可以打印
module1.cool
并获取
。因此,既然
cool
位于主模块的全局名称空间内,那么程序不应该首先在函数
cool
中查找变量
pi
,然后在那里找不到它时,在
main
模块中查找变量
pi
,然后在那里找到它吗

据我所知,解决这个问题的唯一方法是在
module1.py
中导入数学模块。我不喜欢这样的想法,因为这会让事情变得更复杂,而且我喜欢漂亮、简单的代码。我觉得我接近于掌握名称空间,但在这方面需要帮助。谢谢。

“显式优于隐式”是由Python的创建者做出的设计决策(启动Python并运行
导入此

因此,当您运行
module1.cool()
时,Python不会在
main
模块中查找未定义的
pi


无论何时需要使用数学模块,都必须显式地将其导入,这正是Python的工作方式


另外,您应该避免使用X导入*样式的导入,这也是一种不好的做法。在这里,您可以执行:
从数学导入pi

在模块内部,您可以简单地从math import pi定义
,这只会从math导入pi,而不会从整个数学模块导入pi。

回溯显示,问题不在
main.py
,而在
module1.py
中:

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()
def cool():

    print pi
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
import module1

def wow():
    print module1.pi

wow()
module1.cool()
from math import pi

def cool():
    print pi
回溯(最近一次呼叫最后一次):
文件“Z:\Python\main.py”,第10行,在
模块1.cool()
文件“Z:\Python\module1.py”,第3行,冷却
打印圆周率
NameError:未定义全局名称“pi”
换句话说,在
module1
中,没有全局名称
pi
,因为您还没有在那里导入它。当您在
main.py
中执行
from math import*
操作时,只会将
math
模块名称空间中的所有内容导入
main
模块名称空间,而不是导入每个模块的名称空间

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

因此,如果您想使用来自
module1
pi
,您必须在
module1.py
中执行来自数学导入的
。(或者您可以找到其他方法来注入它,例如,
module1.py
可以从主导入*
中执行
,或者
main.py
可以执行
module1.pi=pi
,等等。或者您可以将
pi
填充到神奇的
内置模块中,或者使用各种其他技巧选项是在希望导入的位置执行导入操作。)



作为旁注,除了交互式解释器或偶尔的顶级脚本之外,您通常不希望从foo import*
执行
。也有例外(例如,一些模块明确设计为这样使用),但经验法则是要么
导入foo
,要么从foo导入栏baz

使用有限的
,正如其他人所说,在
模块1
中实际上没有全局
pi
。这是一个很好的解决方案,它只从
math
导入
pi
一次,并明确确保您得到的
pi
是来自
module1
的:

main.py

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()
def cool():

    print pi
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
import module1

def wow():
    print module1.pi

wow()
module1.cool()
from math import pi

def cool():
    print pi
module1.py

from math import *
import module1

def wow():

    print pi


wow()
module1.cool()
def cool():

    print pi
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
import module1

def wow():
    print module1.pi

wow()
module1.cool()
from math import pi

def cool():
    print pi

@abarnert评论中提到的
exec
(python 3)或
execfile
(python 2)的简单方法可能对某些工作流有用。只需将导入行替换为:

exec( open("module1.py").read() )       # python 3
然后,您只需使用
cool()
而不是
module1.cool()
调用函数。在
cool()
中,变量
pi
的行为将类似于一个全局变量,正如OP最初预期的那样

简而言之,这只是隐藏了一个函数定义,否则它会出现在主程序的顶部,并且既有优点也有缺点。对于具有多个模块和导入的大型项目,使用
exec
(而不是适当的名称空间)可能是一个错误,因为您通常不希望在单个全局名称空间中保留太多内容

但是对于简单的情况(比如使用Python作为shell脚本)
exec
提供了一种简单而简洁的方法,可以隐藏共享函数,同时让它们共享全局名称空间。请注意,在这种情况下,您可能需要特别考虑如何命名函数(例如,使用
v1_-cool
v2_-cool