2016-03-05 29 views
0

我在那裏,我試圖從一個封閉訪問父範圍的字符串一些Python代碼,但每當我試圖訪問它,我得到的錯誤:無法從閉包訪問父字符串?

UnboundLocalError: local variable 'my_string' referenced before assignment

什麼也奇怪的是,我有一個列表定義在與字符串相同的範圍內,但我沒有問題訪問變量。

我創建的代碼的簡化版本,它演示了此問題:

def test(): 
    def f1(): 
     print my_list 
     print my_string 
     my_string += "test" 
    my_string = "1" 
    my_list = [1,2,3] 
    f1() 
test() 

當我執行此我得到的輸出:

[1, 2, 3] 
Traceback (most recent call last): 
    File "test.py", line 9, in <module> 
    test() 
    File "test.py", line 8, in test 
    f1() 
    File "test.py", line 4, in f1 
    print my_string 
UnboundLocalError: local variable 'my_string' referenced before assignment 

爲什麼我能夠訪問列表,但不字符串?我怎樣才能從我的關閉中訪問我的字符串?

我是新來的python和closures,所以如果我在這裏留下了一些東西,請讓我知道。

回答

1

那是因爲你不能修改非本地變量而沒有聲明那就是你想要的。 my_string不是本地變量,因此您需要聲明您想要修改它。在Python3中,您可以將nonlocal mystring放在f1()的開頭。在Python2中,你必須把它變成一個全局變量。要做到這一點,您需要global mystringtest()開頭的f1()開頭。

+0

感謝您的信息。我一直聽說使用'global'是一個很大的禁忌,你認爲在這裏使用它會是最好的解決方案嗎?另外 - 爲什麼我的列表變量是可訪問的,當我用我的字符串變量完全相同的方式嗎? –

+0

我認爲最好的解決方案就是返回字符串,並在'f1()'之外加入'my_string'。 'print'調用並不是真正的問題。如果你刪除'my_string + =「test」',你會看到它打印得很好。我很抱歉,雖然我不能說它爲什麼指向SyntaxError中的那一行。 – zondo

0

將my_string變量更改爲列表或任何其他對象類型以獲取所需的行爲。使用str與list是問題所在。與封閉無關。 檢查的STR和列表基礎clases顯示在內部F1的區別

>>> import inspect 
>>> inspect.getmro(str) 
(<type 'str'>, <type 'basestring'>, <type 'object'>) 
>>> inspect.getmro(list) 
(<type 'list'>, <type 'object'>) 
>>> #taking one step further 
... 
>>> s = 'hello' 
>>> s[0] 
'h' 
>>> s[0] = 'y' 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: 'str' object does not support item assignment 
>>> 

插入行「打印當地人()」,並注意到my_string甚至不是一個地方 打印'#F1:當地人,當地人()