gpt4 book ai didi

python - 在 doctests 中修改全局变量

转载 作者:太空宇宙 更新时间:2023-11-04 05:24:35 26 4
gpt4 key购买 nike

doctest 文档有 a section about execution context .我的解读是,模块中的全局变量是针对每个文档字符串中的测试进行的浅层复制,但不会在文档字符串中的测试之间重置。

根据该描述,我认为以下 doctests 会通过:

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

但是下面的测试通过了!

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

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

为什么会出现这种行为?这与具有独立于执行上下文的全局字典的函数有关吗?

最佳答案

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

$ 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

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

(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 为此创建的 <doctest doc.f> 模块中。让我们继续。

(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 中没有模块浅拷贝范围),即使它最初是从模块复制的,但更改不会反射(reflect)回底层模块,因为这是 global 关键字的操作方式 - 在模块级别,而不是跨模块。

关于python - 在 doctests 中修改全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39238675/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com