首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在doctest中修改全局变量

在doctest中修改全局变量
EN

Stack Overflow用户
提问于 2016-08-31 07:43:40
回答 1查看 1.1K关注 0票数 3

文档测试文档包含a section about execution context。我的理解是,模块中的全局变量是为每个文档字符串中的测试浅复制的,但不会在文档字符串中的测试之间进行重置。

基于这个描述,我认为下面的doctest将会通过:

代码语言:javascript
运行
复制
X = 1


def f():
    """Function F.

    >>> X
    1
    >>> f()
    2
    >>> X
    2
    """
    global X
    X = 2
    return X


def g():
    """Function G.

    >>> g()
    1
    >>> X
    1
    """
    return X

但是下面的测试都通过了!

代码语言:javascript
运行
复制
X = 1


def f():
    """Function F.

    >>> X
    1
    >>> f()
    2
    >>> X
    1
    """
    global X
    X = 2
    return X


def g():
    """Function G.

    >>> g()
    2
    >>> X
    1
    """
    return X

似乎全局变量是在文档字符串之间的测试中共享的?但只能在函数调用中使用?

为什么这是结果行为?这是否与函数具有独立于执行上下文的全局变量字典有关?

EN

回答 1

Stack Overflow用户

发布于 2016-08-31 08:19:28

不完全同意。虽然全局变量确实是浅层复制的,但您实际看到的是全局变量的作用域(使用关键字global),以及它在Python中的模块级的实际操作方式。您可以通过在函数f中紧跟赋值(X = 2)之后放入一个pdb.set_trace()来观察这一点。

代码语言:javascript
运行
复制
$ python -m doctest foo.py
> /tmp/foo.py(18)f()
-> return X
(Pdb) bt
  /usr/lib/python2.7/runpy.py(162)_run_module_as_main()
-> "__main__", fname, loader, pkg_name)
  /usr/lib/python2.7/runpy.py(72)_run_code()
-> exec code in run_globals
  /usr/lib/python2.7/doctest.py(2817)<module>()
-> sys.exit(_test())
  /usr/lib/python2.7/doctest.py(2808)_test()
-> failures, _ = testmod(m)
  /usr/lib/python2.7/doctest.py(1911)testmod()
-> runner.run(test)
  /usr/lib/python2.7/doctest.py(1454)run()
-> return self.__run(test, compileflags, out)
  /usr/lib/python2.7/doctest.py(1315)__run()
-> compileflags, 1) in test.globs
  <doctest foo.f[1]>(1)<module>()
-> f()
> /tmp/foo.py(18)f()
-> return X
(Pdb) pp X
2

是的,在f的作用域中,该值确实是2,但让我们来看看它的全局值。让我们看看它们在当前帧和上一帧中的比较情况。

代码语言:javascript
运行
复制
(Pdb) id(globals())
140653053803048  # remember this number, and we go up a frame
(Pdb) u
> <doctest foo.f[1]>(1)<module>()
-> f()
(Pdb) id(globals())
140653053878632  # the "shallow" clone
(Pdb) X
1
(Pdb) c

啊哈,你可以看到它们实际上不是一回事,而且X确实是1,并且没有被改变,因为全局变量是在<doctest doc.f>模块中创建的,正是出于这个原因。让我们继续。

代码语言:javascript
运行
复制
(Pdb) id(globals())
140653053803048  # hey look, is the SAME number we remember
(Pdb) u
> <doctest foo.g[0]>(1)<module>()
-> g()
(Pdb) id(globals())
140653053872960  # note how this is a different shallow clone

因此,您实际上看到的是doctest中的全局变量与源代码中的全局变量不同(因此g将返回2,因为X实际上是由f在模块中更改的,而不是在doctest模块浅复制作用域中),即使它最初是从模块复制的,但更改不会反映回底层模块,因为这是global关键字的操作方式-在模块级别,而不是跨模块。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39238675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档