2016-08-05 71 views
4

最近我设置了这个例子,并且对结果感到惊讶。我将与代码演示了这一点:Python多模块全局变量。 Python中的错误?

文件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位

+0

'from b import *'是不好的形式(并且模糊在这种情况下发生的事情是其中一个原因)。考虑'输入b'并使用'b.delta'来代替。这是更明确的,_and_将实际上按照您的预期工作。 – marcelm

回答

5

当你做参考,我使用Python 3.5.2

from b import *

a.py

,它进口的模块b中定义的所有名称(包括delta)进入a的名字空间。由于Python中不可变类型的float,您可以考虑a.deltab.delta完全分离的变量,指向不同的值。 因此,第一个print()打印的初始值为a.delta,而第二个打印的更新值为b.delta

+0

谢谢,这似乎解释它! –

2

from b import *在您的a模块全局变量中创建一系列新的引用。这些副本中的每一个都从b名称中复制参考。然而它们是独立的全局变量。

请记住,在Python中,名称只是标签;他们被绑在物体上。您可以通过赋值创建该关系,并且可以为每个对象创建多个标签。这就是发生在这里的事情,您在b中标注标签,在a中标注标签,在from b import *之后,两个模块中的标签都指向相同的对象。

但是,您随后将不同对象分配给b中的delta名称。现在,该标签不再引用旧的浮动对象0.0。但是你没有改变a中的delta标签与什么关联。

如果您要将名称作为模块名称的前缀,您将获得a.deltab.delta;分配b.delta = 1不会改变a.delta,他们住在不同的命名空间。

您可能想了解Python名称的工作方式;看到Ned Batchelder出色的Facts and myths about Python names and values presentation

+0

你的条款在答复混淆了我。在|中,从b导入a后,它们引用相同的对象|,从b导入a?是对的吗? –

+0

@EkeymeMo:我不确定我是否按照你的评论,对不起。 –

+0

对不起,我之前的评论是在手机上写的,我不能插入高亮特征。在你的答案中,你说'从b导入后,他们指的是相同的对象',我想你想说的是'...从b导入* ...'。是对的吗? –