最近我设置了这个示例,并对结果感到惊讶。我将用代码演示这一点:
文件1:b.py:
delta = 0.0
def example():
global delta
delta = 1
def ret_delta():
return delta
文件2:a.py:
from b import *
example()
#WHY ARE THESE DIFFERENT?
print(delta) # prints: 0.0
print(ret_delta()) # prints: 1
这没有道理!为什么访问变量并调用返回该变量的函数会有什么不同?
为了供您参考,我在Windows 32位上使用python 3.5.2
进行时
from b import *
在a.py
中,它将模块b
中定义的所有名称(包括delta
)导入到a
的命名空间中。作为Python中不可变类型中的float
,可以将a.delta
视为与b.delta
完全独立的变量,指向不同的值。因此,第一个print()
打印a.delta
的初始值,而第二个打印b.delta
的更新值。
from b import *
在a
模块全局中创建一系列新引用。其中每一个都从b
名称中复制引用。然而,它们是独立的全局变量。
请记住,在Python中,名称只是标签;它们与对象"绑定"在一起。您可以通过指定来创建这种关系,并且每个对象可以创建多个标签。这就是这里发生的情况,b
中有标签,a
中有标签。在from b import *
之后,两个模块中的标签都指向相同的对象。
但是,随后将不同的对象分配给b
中的delta
名称。现在,该标签不再引用旧的0.0
浮动对象。但你没有改变a
中delta
标签的绑定。
如果在名称前面加上模块名称,则会得到a.delta
和b.delta
;分配b.delta = 1
不会改变a.delta
,它们位于不同的命名空间中。
您可能想了解Python名称是如何工作的;请参阅Ned Batchelder关于Python名称和值的精彩演示。