Python 修改doctests中的全局变量

Python 修改doctests中的全局变量,python,global-variables,doctest,Python,Global Variables,Doctest,doctest文档已经发布。 我的理解是,模块中的全局变量对于每个docstring中的测试是浅拷贝的,但是在docstring中的测试之间不会重置 基于这一描述,我本以为以下博士会通过: X = 1 def f(): """Function F. >>> X 1 >>> f() 2 >>> X 2 """ global X X = 2 return

doctest文档已经发布。 我的理解是,模块中的全局变量对于每个docstring中的测试是浅拷贝的,但是在docstring中的测试之间不会重置

基于这一描述,我本以为以下博士会通过:

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
似乎全局文件是跨docstring的测试共享的? 但仅在函数调用中

为什么会出现这种行为?
这是否与函数具有与执行上下文分离的全局字典有关?

不完全如此。虽然globals确实是浅层复制的,但您实际看到的是globals的范围(使用关键字
global
)以及它在Python模块级的实际操作方式。您可以在赋值后立即插入一个内部函数
f
X=2

啊哈,你可以看到它们实际上不是同一个东西,
X
确实是
1
,并且没有改变,因为全局变量在doctest为此创建的
模块中。让我们继续

(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
(Pdb)id(globals())
140653053803048?嘿,看,是我们记得的那个号码吗
(Pdb)u
> (1)()
->g()
(Pdb)id(globals())
140653053872960#注意这是一个不同的浅克隆
因此,您实际看到的是,doctest中的globals与源代码中的globals不同(因此
g
将返回
2
,因为
X
实际上是在模块中由
f
更改的,而不是在doctest模块浅拷贝范围中),尽管它最初是从模块复制的,但更改不会反映回基础模块,因为这是
global
关键字的操作方式-在模块级别,而不是跨模块

(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
(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