簡體   English   中英

Python在嵌套函數中覆蓋變量

[英]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),規則是匿名對象制作其外部環境的硬拷貝,在這種情況下是外部范圍的變量。 因此,如果外部變量是一個不可變的( intchar ),它們不能被匿名對象修改,因為它們是按復制的,而如果它是一個可變的( collectionobjects ),它們可以被更改......因為它們被復制通過“ 指針 ”(他們在內存中的地址)

如果您了解編程,請將其視為按值傳遞並通過引用傳遞。

在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM