在python中导入到导入器范围的名称

时间:2012-06-09 19:11:33

标签: python namespaces

有两个脚本:

#imptee.py
foo = "abc"

def show():
    print "foo from imptee:",foo

#impter.py:

#!/usr/bin/env python

from imptee import *

show()

foo = 123

print "foo from impter:",foo
show()

当我运行impter.py时,会产生以下结果:

  

foo from imptee:abc

     

来自impter:123

     

foo from imptee:abc

我只是不明白为什么在将123分配给变量foo之后,show()仍然打印'abc',而不是123.我认为在“来自imptee import *”之后,foo和show()现在在全局命名空间中,并且没有本地命名空间。我确实理解搜索序列应该是:本地命名空间,全局命名空间,bulit-ins namespece。那么,为什么呢?有人可以帮我一把吗? THX!

3 个答案:

答案 0 :(得分:3)

Python中所谓的“全局命名空间”实际上是模块命名空间。每个模块都有一个,它们是独立的。因此,从*导入imptee会将对象引用imptee复制到__main__; imptee即使在事实之后仍然有自己的命名空间,show()无论如何都有引用。

答案 1 :(得分:1)

因为语句from imtee import *(大约)与from imptee import foo相同,后者({近似)与import imptee; foo = imptee.foo相同。所以fooimptee中没有变化,原因与为两个变量分配相同的值相同,然后更改其中一个变量不会改变另一个变量的值:

>>> a = "hello"
>>> b = a
>>> a
'hello'
>>> b
'hello'
>>> b = 'world'
>>> a
'hello'
>>> b
'world'

此外,正如其他答案所指出的那样,“全局”命名空间实际上是“模块的全局”,而不是“所有模块的全局”。可以通过导入模块然后设置相应的属性来更改其他模块中的全局变量:import imptee; imptee.foo = "bar"

答案 2 :(得分:1)

模块具有单独的命名空间。从一个模块导入到另一个模块时,您将从源模块导入值(通常是函数,但在本例中为文字“abc”),并将它们分配给目标模块中的名称。

执行from imptee import *时,您将它们分配给源模块中的名称,但实际上并不会更改源模块中的指针。它只是重复名称。

在导入后更改目标模块中的赋值时,这不会更改源模块中的任何内容,因为即使名称看起来相同,它们也是单独的指针,并且可以指向单独的内容。

如果您执行了import imptee,然后手动分配了值foo = imptee.foo,则可能会更清楚。然后您将执行foo = 123,并且有意义的是目标模块中foo的值已更改,但源模块中类似命名的指针的值没有。