Python 具有模块导入的名称空间
我正在学习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
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