3

我有两个文件-

foo1.py -

a = 0;
b = {};
def f():
    global a;
    print "foo1: start a -",a;
    a = 10;
    print "foo1 changed a to :",a;
    global b;
    print "foo1: start b - ",b;
    b['me'] = 'fool';
    print "foo1 changed b to :",b;

foo2.py -

from foo1 import *
print "foo2 a before f:", a
print "foo2 b before f:", b
f();
print "foo2 a after f:",a
print "foo2 b after f:",b

当我运行 python foo2.py 时,我看到了这个 -

foo2 a before f: 0
foo2 b before f: {} <br/>
foo1: start a - 0
foo1 changed a to : 10
foo1: start b -  {}
foo1 changed b to : {'me': 'fool'}
foo2 a after f: 0 // **Doesn't change**
foo2 b after f: {'me': 'fool'} // **Changes**

有人可以解释一下吗?

4

2 回答 2

6

你认为a = 10并且b['me'] = 'fool'正在做同样的事情,但事实并非如此。前者将名称绑定a到一个新值;后者改变 中的值b。分配给一个裸名永远不会修改对象;它只会重新绑定名称。

f它何时a = 10将名称重新绑定a到新对象,但这对 没有影响foo2.py,因为foo2py已经导入了旧对象。什么f时候b["me"] = "fool",它会改变已经存在的同一个字典对象。由于foo2.py已导入同一个对象,因此它会看到更改。

于 2012-08-06T09:02:08.820 回答
4

a是不可变的,所以虽然导入的引用foo2不会改变,但名称foo1会重新绑定到一个新值。

b是可变的,因此永远不会反弹;由于两个名称具有相同的引用,因此它们正在查看同一个对象。任何可变对象(列表、集合等)都会发生同样的情况。

于 2012-08-06T08:54:09.373 回答