Python: 修改内部方法内部的方法局部变量

Python: modify method-local variable inside inner method

我正在编写一个名为 test_foo 的测试方法(使用 pytest)。我正在测试函数 foo 的行为,它以另一个函数 get 作为参数。 fooget 的 return 值为条件迭代调用 get,例如:

def foo(get, param):
    max_num_tries = 3
    curr_num_tries = 0
    response = get(param)
    while curr_num_tries < max_num_tries and response.status_code == BAD_STATUS_CODE:
        response = get(param)
    return response

我正在尝试重写 get 以便它可以访问它被调用的次数并且可以相应地 return 不同的值。

这是我目前拥有的简化版本:

def test_foo():
    tries_so_far = 0

    def get(arg1):
        global tries_so_far
        if tries_so_far < 3:
            tries_so_far += 1
            print("do something special here")
        else:
            print("do something else here")
        return "some return val"

    foo(get, "some arg")

但是,我收到以下错误:

NameError: global name 'tries_so_far' is not defined

如果我在 test_foo 之外定义 tries_so_far,在模块级别,我会得到预期的行为。但是,我希望 tries_so_far 成为 test_foo 的局部变量。

有没有办法使用全局变量或其他技术将 get read/write 赋予 tries_so_far?注意:我无法更改 get.

的参数或 return 值

根据这个问题 Why can functions in Python print variables in enclosing scope but cannot use them in assignment? 的已接受答案,Python 3 中添加了一个附加语句:nonlocal 可以满足您的要求。它类似于 global,但表示要查看封闭范围而不是模块级别。因此,以下修改应该可以让您完全按照自己的意愿行事:

def test_foo():
    tries_so_far = 0

    def get(arg1):
        nonlocal tries_so_far
        if tries_so_far < 3:
            tries_so_far += 1
            print("do something special here")
        else:
            print("do something else here")
        return "some return val"

    foo(get, "some arg")

虽然您的问题与我上面引用的问题不完全相同,但您应该阅读已接受的答案。它非常好,可能会解决您对该主题的许多未说明的问题。