python裝飾器 閉包 垃圾講解

2021-10-06 15:36:01 字數 3922 閱讀 1222

第一部分裝飾器,接觸很久,沒理會原理。慚愧。

第二部分裝飾器傳參的小實踐。

第三部分閉包的理解,如果有錯誤,留著,以後再說。

其本意就是在不改變原函式的基礎上,對函式新增功能。用途呢,aop思想,你說是吧。

乙個自己寫裝飾器的例子:

# 定義裝飾器

# 這種寫法比較適合簡單的包裹,只是會把real_func前面「裹住」,

# 在進入realfunc前進行處理

defdecorate

(real_func)

:def()

:print

('this is decoration function'

)# do sth

return real_func(

)

比較一下可以看到,第一種decorate函式返回的是乙個函式而不是乙個值,函式名+括號的時候函式才會執行,所以得func_to_run()才能執行。

那顯然,返回值不能是函式(函式不是「第一類變數」)的語言自然沒有這種用法。

裝飾器的使用,接上文

# 定義帶有裝飾器的函式

@decorate

def whatever():

print('this is real function')

# 執行函式的時候會把裝飾器函式也執行

whatever()

#裝飾器是python的語法糖,以上寫法等同於以下

func_to_run=decorate(whatever)

func_to_run()

如果單單看第一種執行的順序的話

decorate收入whatever作為引數

然後whatever函式執行自己的邏輯 )

whatever(

)是的是的,那為什麼不直接這樣順序寫呢?不是說了嗎aop啊,在不改動原來函式**的基礎上對原函式新增功能。

另:另一種我比較喜歡的裝飾器的寫法,

defdecorate

(real_func)

:def()

:# do sth code

real_func(

)# do sth code

return

以下**寫了乙個guard裝飾器,保證此次函式執行多次進行嘗試,嘗試次數有限,成功繼續下一步,超限退出。

def

guard

(operation_func)

: @functools.wraps(operation_func)

def(

*args,

**kwargs)

: succeed=

false

cnt=

0while

not succeed and cnttry:

operation_func(

*args,

**kwargs)

succeed=

true

except exception as e:

cnt+=

1if cnt==retry_time:

print

("sorry, max retry reached. exit..."

) exit(0)

print

("error: {}, retrying {}..."

.format

(e,cnt+1)

) time.sleep(

2)

然而在使用的時候,driver這個返回值卻是none。

from web import webdriver

# 函式定義

# 執行

driver=makeconnection(

)print

(driver)

# 列印的是none

怎麼driver沒有被返回出來?

其實是因為裝飾器呼叫makeconnection的時候沒有接收並且return引數,儘管makeconnection返回了引數,但是裝飾器函式沒有接收它,更別談返回了。

所以需要修改裝飾器,讓它接收引數並且傳遞。

這是我們需要注意的點。即便是函式本身return了引數,如果裝飾器不接著傳遞下去,引數會在路上被「丟掉」。

修改如下:

def

guard

(operation_func)

: @functools.wraps(operation_func)

def(

*args,

**kwargs)

: succeed=

false

cnt=

0while

not succeed and cnttry:

# 接收引數並且傳遞

elem=operation_func(

*args,

**kwargs)

succeed=

true

if succeed:

return elem

except exception as e:

cnt+=

1if cnt==retry_time:

print

("sorry, max retry reached. exit..."

) exit(0)

print

("error: {}, retrying {}..."

.format

(e,cnt+1)

) time.sleep(

2)

貌似離散數學的閉包,和你們程式設計裡面談的閉包沒有關係啊……

可參考這個知乎

這個概念啊,很操蛋哦,是個模糊的概念,想找起源都找不到。如有,麻煩告知我我再去看看。

其廣泛流傳的概念有兩種

「在函式中訪問到函式外部的變數,這種情況即可稱作閉包」,出處見這裡,就像這個例子。

defa(

):value_a=

199defb(

):print

(value_a)

這玩意就算是個小閉包了。b的作用域中訪問到了value_a,只不過這樣太傻了,而且這樣寫法沒什麼用。

這個概念更加具體些,體現在第乙個概念的具體用途上:「在執行過程完畢後返回函式,將函式和其上下文保留,即形成閉包」,出處這裡。不過這種用途,個人認為,只能在返回值可以是函式的語言上有所體現

這個說法很搞笑,不過也挺生動的,是對這個概念的體現。

這個概念的例子更符合實際用途:

返回的函式(function),攜帶著function外部的environment的量到了environment外面。

def

enrivonment()

: a=

100def

function()

: b=

200return a+b

return function

func_with_enrivonment=enrivonment(

)print

(func_with_enrivonment(

))

Python 裝飾器 ,閉包

1 裝飾器 不改變被裝飾的函式情況下附加一些功能 本質是函式,用於裝飾其他函式,附加一些本身所沒有的功能 實質 是乙個函式 引數 是你要裝飾的函式名 並非函式呼叫 返回 是裝飾完的函式名 也非函式呼叫 作用 為已經存在的物件新增額外的功能 特點 不需要對物件做任何的 上的變動 例1 計算執行時長 i...

python裝飾器和閉包

下面幾個部落格有裝飾器的講解,也包含了裝飾器幾種情況的例子,比如說被裝飾的函式帶引數,裝飾器本身帶引數等。理解python中的裝飾器 python裝飾器學習 例子 其實裝飾器跟設計模式中的裝飾器模式基本一樣,就是在已有的函式上新增新的功能,這也是自己對裝飾器的一點簡陋的理解了。下面是自己寫的簡單例子...

python閉包和裝飾器

要理解裝飾器,就要明白閉包 要明白閉包,首先就要從高階函式和作用域說起 說道作用域,一般會談到legb規則。所謂的legb l locals,當前命名空間 區域性作用域 e enclosing,外部函式的命名空間 外部作用域 g global,全域性的命名空間 b bulit in,內建的命名空間平...