从测试文件访问全局变量

时间:2016-08-10 21:57:12

标签: python

我有一个包含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?似乎如果一个人工作,其他人也应该工作。

1 个答案:

答案 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.rootA.crumbs。这样,这些对象只有一个规范名称,名称由更改它们的模块“拥有”。