我有一个包含2个全局变量的文件A
root = ""
crumbs = []
def read(line):
global root, crumbs
line = line.strip()
open_tag = is_valid_open(line)
kv = get_kv(line)
if open_tag is not None:
root += open_tag + "."
print root <---------- prints stuff
elif kv is not None:
crumbs.append(kv[0] + "=" + kv[1])
print crumbs <---------- prints stuff
我有一个测试,我
from A import read, root, crumbs
我提供了一些数据
read('<a>')
read('<b>')
read('<d>acceptor</d>')
打印结果
print "." + root + "." <---------- prints NOTHING
print "." + str(crumbs) + "." <---------- prints stuff
为什么我可以访问列表但不能访问测试文件中的String?似乎如果一个人工作,其他人也应该工作。
答案 0 :(得分:5)
简而言之,这是因为+=
为列表和字符串做了不同的事情。
字符串是不可变的。因此, A.py 中的root += ...
会创建一个新字符串并将其分配给root
。有两个对root
的引用:一个在 A.py 中,一个在您的测试脚本中。 root +=
行仅更改 A.py 中的root
,因为这是 A.py 中的唯一功能可以访问的内容。测试模块中的root
不会更改。
列表是可变的。因此,crumbs +=
会修改现有列表,并且不会更改crumbs
指向的内容。由于crumbs
仍然引用 A.py 和测试模块中的相同列表,因此您会看到测试模块中的更改。
如果您在没有+=
的情况下编写这些语句,那就更清楚了:
root = root + ...
显然会生成一个新字符串并将root
更改为指向它crumbs.extend(...)
显然没有制作新列表,并且不会更改crumbs
指向当您尝试在不使用完全限定名称的情况下访问模块之间的变量时,可能会出现这种混淆。您最终会得到多个名称,这些名称最初(在import
之后)引用相同的对象,但稍后会改变这一点。
解决方案仅针对import A
,并在测试脚本中引用A.root
和A.crumbs
。这样,这些对象只有一个规范名称,名称由更改它们的模块“拥有”。