2016-02-12 117 views
0

我在寫一個名爲test_foo(使用pytest)的測試方法。我正在測試函數foo的行爲,該函數將另一個函數get作爲參數。 foo呼籲get反覆,有條件地對get的返回值,例如:Python:修改方法 - 內部方法內的局部變量

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,使得它可以訪問它多少次被調用,並可以相應地返回不同的值。

這裏是我到目前爲止的簡化版本:

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

如果我定義tries_so_fartest_foo,在模塊級別,我會得到預期的行爲。但是,我希望tries_so_fartest_foo的本地變量。

是否有某種方法可以使用全局變量或其他技術對get進行讀取/寫入tries_so_far?注意:我無法更改參數或返回值get

+0

您似乎沒有對'tries_so_far'使用寫入權限。只要刪除'global',它就可以讀取變量。 「全局」意味着「模塊級別」,正如您已經正確確定。 –

+0

對不起 - 我忘了添加到我的例子。更新。 – LateCoder

+0

我假設你從打印語句中使用Py3k。如果那是真的,你能改變標籤嗎? –

回答

2

根據這個問題的接受答案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") 

雖然你的問題是不是我上面提到的完全相同的副本,你應該閱讀接受的答案。這非常好,可能會解決你在這個問題上有很多未提到的問題。