Python閉包及裝飾器

2022-07-04 08:15:09 字數 2902 閱讀 8216

先看乙個例子:

def

outer(x):

definner(y):

return x+y

return

innder

add = outer(8)

print add(6)

我們定義了乙個方法outer,方法內部又定義了乙個方法inner,方法outer返回值為內部定義的方法inner。

同時,內部方法innder使用了外部方法的引數x。

從我們的呼叫方式可以清晰地看到,add=outer(8)相當於add接受了類似於下邊乙個方法

def

inner(y):

return 8+y

然後呼叫add(6),結果顯示14

這其實就是乙個簡單的閉包。

python中的閉包從表現形式上定義(解釋)為:如果在乙個內部函式裡,對在外部作用域(但不是在全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure)。

def

tsfunc(func,x):

def

print func.__name__

return

func(x)

return

deffoo(x):

print

'aaa

' +x

if__name__=='

__main__':

tsfunc(foo , "x

")

結果是:

fooaaax

我們把方法foo當做引數傳遞到另乙個方法tsfunc內,然後在tsfunc內做了其他一些事情(這裡我們只是列印了foo的name),最後又返回來foo,並使用了額外引數。

和上邊一樣,舉個例子,如下:

def

decorator(f):

defnew_f(a, b):

print

"input

", a, b

return

f(a, b)

return

new_f

@decorator

defsub(a,b):

return a-b

defadd(a,b):

return a+b

print sub(3,4

)add

= decorator(add)

print add(3, 4)

結果如下:

input 3 4

-1input 3 4

7對比sub的呼叫和add的呼叫,其實他們是完全一樣的執行方式,只不過裝飾器將語法包裹起來,看起來更乾淨一些。

或許你現在發現乙個問題,如果我們要給裝飾器加引數,在被裝飾的方法內部使用該怎麼做呢?

在裝飾器基礎上再增加一層巢狀,其定義和實現裝飾器是一樣的,看下邊的例子:

#

def pre_str(pre=''

):

#old decorator

defdecorator(f):

defnew_f(a, b):

print(pre + "

input

", a, b)

return

f(a, b)

return

new_f

return

decorator

@pre_str(

'^_^')

defsub(a,b):

return a-b

defadd(a,b):

return a+b

print sub(3,4)

dec = pre_str('

&_&'

)add =dec(add)

print add(3, 4)

這個也是很好理解的了吧,我們的裝飾執行方式和分步呼叫是同乙個效果的。

這樣就實現了裝飾器語法傳遞引數,效果還不錯。

看下邊例子:

def

decorator(aclass):

class

newclass:

def__init__

(self, age):

self.total_display =0

defdisplay(self):

self.total_display += 1

print

"total display:%s

" %self.total_display

return

newclass

@decorator

class

bird:

def__init__

(self, age):

self.age =age

defdisplay(self):

print

"my age is %s

"%self.age

eaglelord = bird(5)

for i in range(3):

eaglelord.display()

執行結果:

定義了decorator作用給類bird,當初始化bird類時,裝飾器會先進行初始化,使用bird初始化的引數,然後返回乙個裝飾器內定義的類。

例子中裝飾器內的類包裹了乙個bird類例項,並例項化。根據單步除錯來看,bird類初始化只進行了一次,即相當於bird的初始化時在裝飾器內被呼叫生成例項時呼叫的。

要注意的是:bird(5)的返回值並不是bird例項,而是裝飾器內的類newclass例項

那麼剩下的就是很簡單的方法呼叫了。

Python 閉包及裝飾器

閉包是指延伸了作用域的函式。自由變數 free variable 指未在本地作用域中繫結的變數 函式裝飾器用於在原始碼中標記函式,以某種方式增強函式的行為。裝飾器實質,把被裝飾的函式替換為新函式,二者接收相同的引數,繫結了被裝飾函式最為自由變數,返回被裝飾函式本該返回的值,同時還會做些額外操作 裝飾...

Python 裝飾器 ,閉包

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

Python3 閉包及裝飾器

一.什麼是閉包 不同程式語言實現閉包的方式是不同的,python中閉包從表現形式上看,如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 舉個例子 def outer x def inner y return x y return ...