作用域

摘要

函數(shù)的作用域是一個(gè)默認(rèn)的因素,寫程序時(shí)一定要清楚,閉包、lambda中對(duì)待作用域的方式,筆者遇到了函數(shù)式編程的作用域問題,于是進(jìn)行了初步解讀。

閉包

我們先看看John如何定義閉包
"An object is data with functions, A closure is a function with data" --John D. Cook
閉包中內(nèi)函數(shù)修改外函數(shù)局部變量
在基本的python語法中,一個(gè)函數(shù)可以隨意讀取全局變量,但是要修改全局?jǐn)?shù)據(jù)的時(shí)候有兩種辦法

  1. global聲明全局變量
  2. 全局變量是可變數(shù)據(jù)類型時(shí)可以修改

閉包內(nèi)函數(shù)也是類似的情況,在內(nèi)函數(shù)中想修改閉包外部變量,外函數(shù)綁定給內(nèi)函數(shù)的局部變量 的時(shí)候哦:
1 在python3中可以用nonlocal關(guān)鍵字聲明一個(gè)變量,表示這個(gè)變量不是局部變量空間的變量,需要到上一層變量空間棧找這個(gè)變量。
2 在python2中沒有nonlocal這個(gè)關(guān)鍵字,我們可以吧閉包變量改成可變數(shù)據(jù)類型數(shù)據(jù)進(jìn)行修改,比如列表。

作用域

python引用變量的順序

  1. 當(dāng)前作用域局部變量
  2. 外層作用域變量
  3. 當(dāng)前模塊中的全局變量
  4. python內(nèi)置變量
    在調(diào)用時(shí)有幾個(gè)注意事項(xiàng):
  5. 沒有塊級(jí)作用域: 代碼塊里的變量,外部可以調(diào)用
  6. 局部作用域: 例如函數(shù)內(nèi)部作用域
  7. 作用域鏈:變量會(huì)由內(nèi)到外,先去自己作用域去找,沒有的話再去上級(jí),直到找不到報(bào)錯(cuò)
  8. 記住在函數(shù)未執(zhí)行之前,作用域已經(jīng)形成了,作用鏈也生成了
  9. 聲明全局變量global,如果局部要對(duì)全局變量進(jìn)行修改,需要在局部聲明該全局變量
  10. nonlocal關(guān)鍵字用來在函數(shù)或其他作用域中使用外層(非全局)變量
name = "global"

def f1():
    print(name)

def f2():
    name="local"
    f1()

def f3():
    global name
    name="global_edit"
    f1()

f2()
f3()

lambda

lambda作為一個(gè)表達(dá)式,定義了一個(gè)匿名函數(shù),一般用來創(chuàng)建短小的匿名函數(shù)
lambda并不對(duì)帶來程序運(yùn)行效率的提升,只會(huì)增加代碼更簡(jiǎn)潔
lambda形式可以從外部作用域引用變量
lambda簡(jiǎn)化了函數(shù)定義的書寫形式,使得代碼更為簡(jiǎn)潔,對(duì)于不熟悉的人降低了代碼的可讀性
匿名函數(shù):沒有名稱的函數(shù),由編譯器指定名稱并分配空間,通常直接做參數(shù)傳遞
例子:

# 新浪面試題
li = [lambda :x for x in range(10)]
res = li[0]()

循環(huán)后x變成了9,li相當(dāng)于每個(gè)函數(shù)都輸入x即9的列表

對(duì)比上個(gè)例子

x = [(lambda x=x:x) for x in range(3)]
x[0]()
0
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容