[英]Python overwriting variables in nested functions
假設我有以下python代碼:
def outer():
string = ""
def inner():
string = "String was changed by a nested function!"
inner()
return string
我想調用outer()來返回“String被嵌套函數改變了!”,但我得到了“”。 我得出結論,Python認為行string = "string was changed by a nested function!"
是inner()本地新變量的聲明。 我的問題是:如何告訴Python它應該使用outer()字符串? 我不能使用global
關鍵字,因為字符串不是全局的,它只存在於外部范圍內。 想法?
在Python 3.x中,您可以使用nonlocal
關鍵字:
def outer():
string = ""
def inner():
nonlocal string
string = "String was changed by a nested function!"
inner()
return string
在Python 2.x中,您可以使用包含單個元素的列表並覆蓋該單個元素:
def outer():
string = [""]
def inner():
string[0] = "String was changed by a nested function!"
inner()
return string[0]
您還可以使用函數屬性來解決這個問題:
def outer():
def inner():
inner.string = "String was changed by a nested function!"
inner.string = ""
inner()
return inner.string
澄清:這適用於python 2.x和3.x.
這種情況經常發生在我身上,當我編寫一個函數時,我突然意識到擁有一個更小的輔助函數可能是一個好主意,但在其他任何地方都沒有用。 這自然讓我想把它作為嵌套函數在里面定義。
但我有使用JAVA匿名對象的經驗(即:定義一個runnable),規則是匿名對象制作其外部環境的硬拷貝,在這種情況下是外部范圍的變量。 因此,如果外部變量是一個不可變的( int
, char
),它們不能被匿名對象修改,因為它們是按值復制的,而如果它是一個可變的( collection
, objects
),它們可以被更改......因為它們被復制通過“ 指針 ”(他們在內存中的地址)
如果您了解編程,請將其視為按值傳遞並通過引用傳遞。
在python中,它非常相似。 x=123
是一個賦值,它們給變量xa新的含義(不修改舊的x), list[i]/dict[key]
是對象訪問操作,它們真的修改了東西
總而言之,你需要一個可變對象......為了修改(即使你可以使用[]訪問一個元組,你也不能在這里使用它,因為它不可變)
要添加到Sven的答案 :
在Python 2.x中,您只能從內部范圍讀取外部范圍變量。 分配將只創建一個隱藏外部范圍的變量的新本地(即內部范圍)變量。
如果要讀取和修改 ,可以使用dict
將變量保存在外部作用域中,然后通過內部作用域中的dict訪問它們,同時在存在多個外部作用域的情況下保持代碼相當干凈和可讀 :
def outer():
# hold some text, plus the number of spaces in the text
vars = {'text': 'Some text.', 'num_spaces': 1}
def inner():
# add some more text
more_text = ' Then some more text.'
vars['text'] += more_text
# keep track of the number of spaces
vars['num_spaces'] += more_text.count(' ')
inner()
return vars['text'], vars['num_spaces']
輸出:
>>> outer()
('Some text. Then some more text.', 5)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.