第15條 閉包內使用外圍作用域的變數

2021-10-03 03:32:57 字數 3163 閱讀 8038

python的閉包:是一種定義在某個作用域d中的函式f,這種函式f引用了作用域d裡面的變數。

案例1:將values列表中的數字進行排序,同時位於group中的數字放在不屬於group中元素之前。

def

sort_priority

(values,group)

:def

helper

(x):

if x in group:

#引用了上層作用域中的變數

return(0

,x)return(1

,x) values.sort(key=helper)

案例2:在案例1的基礎上,返回values中是否出現了在group中的元素標誌位found

def

sort_priority

(values,group)

: found =

false

defhelper

(x):

if x in group:

found =

true

return(0

,x)return(1

,x) values.sort(key=helper)

return found

if __name__ ==

"__main__"

: values =[1

,2,4

,9,92

,100

] group =[1

,2,100

] found = sort_priority(values,group)

print

(values)

print

(found)

輸出結果:

[1,

2,100,4,

9,92]

false

可以看出,排序的結果是對的,found的返回值應該是true,但卻是false

這就需要考慮python在引用變數和賦值時的規則。

1.引用變數時,python直譯器遍歷作用域的順序:

2.給變數賦值時,規則則有所不同。

如果當前作用域已經定義了這個變數,那麼該變數就會具備新值。若是當前作用於內沒有這個變數,python則會把這次賦值視為對該變數的定義,使其稱為區域性變數。

可以看出,案例2中的helper函式中的found = true,被視為建立了helper函式作用域內的區域性變數,而並非外部變數(包含helper函式的sort_priotityfound

為了避免這種情況的存在,可以採用nonlocal關鍵字,在helper函式中指定found變數,這樣python會在上層作用域中查詢該變數。

def

sort_priority

(values,group)

: found =

false

defhelper

(x):

if x in group:

nonlocal found ###

found =

true

return(0

,x)return(1

,x) values.sort(key=helper)

return found

if __name__ ==

"__main__"

: values =[1

,2,4

,9,92

,100

] group =[1

,2,100

] found = sort_priority(values,group)

print

(values)

print

(found)

nonlocal語句清楚的表明:如果在閉包內給該變數賦值,那麼修改的是閉包外的那個作用域中的變數。這與global語句互為補充,global用來表示修改模組作用域中的變數。

主要區別:

注意點:除了簡單的函式外,盡量不要用nonlocal語句,否則遭到濫用,很難追蹤**異常。

如果使用nonlocal的**,已經寫的越來越複雜了, 可以考慮將相關的函式封裝成輔助類。

class

sorter

(object):

def__init__

(self,group)

:super()

.__init__(

) self.group = group

self.found =

false

def__call__

(self,x)

:if x in self.group:

self.found =

true

return(0

,x)return(1

,x)if __name__ ==

"__main__"

: values =[1

,2,4

,9,92

,100

] group =[1

,2,100

] sorter = sorter(group)

values.sort(key=sorter)

print

(sorter.found)

mysql閉包的作用域 預編譯 閉包 作用域鏈

預編譯 先go後ao ao執行順序先形參定義 變數提公升 形參實參統一 函式提公升並且定義賦值 閉包函式內部 return 乙個內部函式被外部變數接收 外部變數可以使用內部函式 ao 中的值 閉包的好處是可以防止全域性變數汙染,但是閉包多了也會有記憶體洩漏的風險function test1 var ...

js的作用域和閉包

1.作用域 乙個變數的可用範圍 全域性作用域 除了函式內,客廳 區域性作用域 函式內 小房間 全域性變數 在全域性作用域內宣告的變數 客廳裡面的東西 區域性變數 在區域性作用域內宣告的變數 你臥室裡面的東西 全域性作用域不能訪問區域性,區域性作用域可以訪問全域性 2.閉包 用來解決全域性汙染的,用來...

Javascript中的閉包與作用域

要解決的問題是 從方法a中使用方法b裡面定義的變數 閉包 是乙個函式,能夠在函式生成時捕獲附近的 值 參照書本給出的閉包例子 function b function a s var b b b 輸出 1 finished in 0.2s 很滿意,能修改到s的值,原因是在函式生成的時候捕獲了附近的 值...