Python多模块全局变量.python中的一个bug



最近我设置了这个示例,并对结果感到惊讶。我将用代码演示这一点:

文件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浮动对象。但你没有改变adelta标签的绑定。

如果在名称前面加上模块名称,则会得到a.deltab.delta;分配b.delta = 1不会改变a.delta,它们位于不同的命名空间中。

您可能想了解Python名称是如何工作的;请参阅Ned Batchelder关于Python名称和值的精彩演示。

最新更新