求幫助,Python閉包和返回函式問題?

時間 2021-06-02 12:36:44

1樓:

感覺我已經理解清楚了,來回答下……

1、列表不是函式。一般1個閉包返回1個函式,這裡你可以理解為3個函式是3個閉包,想要3個一起返回,但是返回只能有1個引數,怎麼辦呢?只好用裝在列表裡返回。

你看返回後的列表也是拆給了f1,f2,f3。

2、回答第二個問題,需要區分count和count(),不加括號是函式本身,加括號是函式執行後的返回值。首先f1,f2,f3=count(),右邊的count()是呼叫函式count的返回值,也就是列表,列表中的元素是函式,所以結果就是f1,f2,f3各自拿到乙個函式。下一句f1(),就是執行這個函式……

3、f1,f2,f3=count(),f1在這裡定義過。

2樓:500ServerError

閉包就是自帶BGM的男人

這個BGM叫執行環境,一般是一堆變數

```python

def foo():

a=1b=2

def bar():

print(a+b)

return bar

#注意不是return bar()

print([cell.cell_contents for cell in foo().__closure__])

#輸出是[1,2]

所謂的closure就是這些`BGM`,而且是按照與目標函式(此處是bar)的距離壓棧的,壓的是cell物件

雖然用字典來表明closure很容易理解,但是我覺得用棧來理解更好的說明為什麼這個作用域叫closure(閉包),這裡的close可以理解為接近,而不是關閉

至於閉包是什麼意思,目標就是自帶執行環境,不讓外部變數(local,global,build-in)汙染執行環境,這一點在JS中尤其能體現

3樓:miss grace

大神好,剛碰到乙個閉包問題,看到知乎,前來請教。code跟大神的一樣

不幸的是,我的結果為

所以後面的就沒再看了,用的Python 2.7.6, ubuntu14.04, 如有錯誤還請指正,嘿,thanks~

4樓:黃光星

我覺得文中的例子對初學者不太友好,裡面同時混雜幾個不同的問題。

因為涉及問題太多了,我也不期待能夠一下說明白,盡力而為。

(1)unpack tuple和list, 可以讓函式返回多個值

defcount

():return(1

,2,3

)# 或者 return [1, 2, 3]

# 把列表解包,把1 2 3 分別賦值給 a b ca,

b,c=

count

()printa,

b,c# 輸出 1, 2, 3

(2)假設你知道Python的dict型別。Python中,在函式中定義乙個變數的時候,會在乙個隱藏的叫locals的dict裡面插入key-value,其中key是變數名,value是變數值。而引用乙個變數的時候,則首先會在這個叫locals的dict裡面,根據變數名作為key,去查對應的值。

var=

1# 你可以認為這裡進行了 locals['var'] = 1 的操作

print

var# 在對var變數進行求值的時候,就在locals['var']裡面找var變數對應的值

(3)for迴圈中,每次迴圈只是給 `i` 重新繫結值

foriin(

1,2,

3):print

iprint

i# 一次輸入 1 2 3 3

每次`for i in (1, 2, 3)`相當於在`print i`之前,進行了

`locals['i'] = 1`

`locals['i'] = 2`

`locals['i'] = 3`

的操作所以最後的`print i`再去locals字典裡面找`i`的時候,就變成 3 了。

(4)閉包是乙個函式加上這個函式引用的外部變數

var=

1def

f():

print

var# 這裡的閉包是函式 f 和 f 引用的外部變數 var

defcount

():var2=2

deff

():print

var2

# 這裡的閉包是函式 f 和 f 引用的外部變數 var2

return

f拿第乙個函式 f 來說。在 f 執行的時候,直譯器拿著'var'這個字串去locals字典裡面找,發現找不到,於是在closure字典裡面找,最後closure字典裡面找,你可以認為就是找closure['var'],然後發現找到對應的值。count裡面的 f 函式同理。

(為了容易理解,我這裡說謊了。實際上 f 壓根沒有closure,count裡面的 f 才有。其實closure壓根不是像locals那樣的字典)

(5)函式定義時,函式只是記錄變數的名字。

要區分什麼是名字,什麼是值。

`i = 1`這裡 i 只是名字,只是乙個字串 'i' 。這句話執行完,locals['i'] = 1,就說 i 對應的值是1

defcount

():fs=

fori

inrange(1

,4):# 定義乙個函式,等價於執行了 locals['f'] = 真正生成的函式

# 每次迴圈,這裡都會重新生成乙個函式,然後把重新生成的函式賦值給 locals['f']

deff

():returni*

i# 引用了'i'這個名字,但並不是引用了'i'對應的值

# f 不是函式,它只是乙個名字'f'。f 引用的東西,也就是locals['f']才是真正的函式fs.

(f)# 於是這個for迴圈生成了三個函式,這三個函式是沒有名字的,這個函式執行完後,它們跟'f'這個名字就毛關係都沒有了(是的我說慌了,但可以先不管)

# 把整個列表返回,這個列表包含了三個函式

return

fs# count()返回三個函式的列表,unpack 列表的語法把列表中的三個函式抽出來,重新給他們命名為 f1, f2, f3

# 也就是說,

# locals['f1'] = 列表中的第1個函式

# locals['f2'] = 列表中的第2個函式

# locals['f3'] = 列表中的第3個函式

# 這三個函式跟'f'這個名字現在毛關係都沒有。(其實是有的,但為了說明需要簡化,現在你可以完全不管括號裡面說的話)f1,

f2,f3=

count

()print

f1(),

f2(),

f3()

# 好了我們執行它們,輸入都是 9

# def freturn i * i

這是因為 f1 現在對應的函式,裡面引用了 'i' 這個字串,我們根據 'i '這個字串去找它對應的值,先找到 f 當前的locals字典,發現沒有,因為函式定義的時候沒有定義 i 變數。然後再去closure['i']裡面找,因為Python是通過closure字典實現閉包的(就當它是對的好不好),所以我們可以在closure['i']找到值,這個值就是我們上一次執行的時候count函式裡面殘留的locals['i'],而由於for迴圈三遍之後,locals['i'] == 3,所以找到 i 的值就是3。所以最後輸出都是9

5樓:狼大人

幾個函式位於同乙個 closure 裡,所以最後使用的是同乙個變數——變數的值在 outer 函式執行過程中被變成最後乙個值,就是你看到的。

Q.E.D.

(順便,你補充裡的幾個問題只說明……你對 Python 語法對理解還沒到可以看 closure 這些東西的時候。什麼叫「計算列表」?什麼叫「直接把列表fs返回了」?

什麼叫「括號內賦值呼叫」?還有 f1, f2, f3 = count() 是啥?——先把這些搞明白了,再研究「為什麼結果都是 9」。

深入淺出python閉包

小圈圈 究竟哪種口罩才有防霾效果呢?1 普通醫藥口罩能抗霧霾?沒有防霾效果。普通的紗布口罩對PM2.5的過濾在20 左右,是用來擋住大號的顆粒物的,它們中的大部分對小號懸浮顆粒 比如PM2.5 沒啥作用,而且還可能漏氣.2 棉布 活性炭口罩能抗霧霾?沒有防霾效果。棉布等材質還會滋生細菌,藏汙納垢 劣...

如何在Python高階閉包中得到最外層函式的環境變數?

已登出 你不shadow不行嗎 shadowing的用意就是隱藏外層作用域的變數,你這 我要用同名變數隱藏掉外層,還要能有辦法訪問到外層 這邏輯真的太矛盾了。def fn1 a 11 def fn2 b 22 def fn3 print a return fn3 return fn2 a 0 f2 ...

javascript的閉包的概念和ruby的閉包的概念有何異同?

蛙二 概念沒區別,但實現手法有小區別。很多語言 除JS,還有Lua,Scheme 實現閉包的詞法定界,會沿著作用域鏈一層層向上查詢,並把這個詞法範圍內的變數在閉包中另存乙份實體 非引用 而Ruby的作用域規則不允許鏈式地向作用域外查詢,只有用define method消除作用域牆,使原本隔離開的作用...