天天看點

傳回函數

閉包:

在函數A中又定義了函數B,并且,内部函數B可以引用外部函數A的參數和局部變量,當A傳回函數B時,相關參數和變量都儲存在傳回的函數中,這種稱為“閉包(Closure)”的程式結構擁有極大的威力。

利用閉包傳回一個計數器函數,每次調用它傳回遞增整數:

第一種方法:

# -*- coding: utf-8 -*-

def createCounter():
    n=0
    def counter():
        nonlocal n              #必須加nonlocal
        n=n+1
        return n
    return counter

# 測試:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('測試通過!')
else:
    print('測試失敗!'
      

總結:

這段代碼如果不加nonlocal,會報錯,這是因為對于createCounter函數,n是局部變量,對于counter函數,n是非全局的外部變量。當在counter中對n進行修改時,會将n視為counter的局部變量,屏蔽掉createCounter中對n的定義;如果僅僅在counter中對n進行讀取,則不會出現這個錯誤。

而寫成清單則不會報錯了, 改變清單L中第一個元素的值,但并沒有改變清單L的記憶體位址。

第二種方法:

def createCounter():
    L=[0]               # 清單L的記憶體位址在初次調用時已經給定,且L[0]即第一個元素指向整數0
    def counter():      
        L[0]+=1    #改變清單L中第一個元素的值,但并沒有改變清單L的記憶體位址
        return L[0]
    return counter