python之閉包和裝飾器

2021-09-10 02:47:17 字數 2726 閱讀 8863

閉包函式必須滿足兩個條件:1.函式內部定義的函式 2.包含對外部作用域而非全域性作用域的引用

如下閉包函式:

def callfunc():

n = 1

def show():

print('show: ', n)

return show

s = callfunc()

s()

程式在執行時,callfunc 函式返回了內部定義的 show 函式,並且 在 show 函式內部使用了外部函式的變數。

在 show 函式返回時,儲存了當前的執行環境,也就是會在 show 函式中使用的外部變數 n 。

因為 n 是乙個 callfunc 函式中的區域性變數,正常情況下 callfunc 函式執行結束後,n 就會被釋放。

但是現在因為 callfunc 函式中返回了 show 函式,show 函式在外部還會再執行,所以程式會將 show 函式所需的執行環境儲存下來。

這種形式就是閉包。

裝飾器 本身也是乙個函式 ,作用是為現有存在的函式,在不改變函式的基礎上去增加一些功能進行裝飾。

裝飾器實際上就是乙個函式 ,這個函式以閉包的形式定義

在使用這個裝飾器函式時,在被裝飾的函式的前一行,使用@裝飾器函式名形式來裝飾

import time

def count_time(func):

start = time.time()

func()

end = time.time()

print('共計執行:%s 秒'%(end - start))

@count_time

def my_count():

s = 0

for i in range(10000001):

s += i

print('sum : ', s)

my_count()

這種不改變原有函式功能基礎上,對函式進行擴充套件的形式,稱為裝飾器。

在執行 @*** 時 ,實際就是將 原函式傳遞到閉包中,然後原函式的引用指向閉包返回的裝飾過的內部函式的引用。

無參無返回值

def setfunc(func):

print('start')

func()

print('end')

@setfunc

def show():

print('show')

show()

2、無參有返回值

def setfunc(func):

print('start')

return func()

@setfunc # show = setfunc(show)

def show():

return 100

print(show() * 100)

3、有參無返回值

def setfunc(func):

print('start')

func(s)

print('end')

@setfunc

def show(s):

print('hello %s' % s)

show('tom')

4、有參有返回值

def setfunc(func):

print('start')

return func(x, y)

@setfunc

def myadd(x, y):

return x + y

print(myadd(1, 2))

根據被裝飾函式的定義不同,上面細分了四種形式,那麼能否利用學過的技術,實現一種適用於任何形式函式定義的裝飾器呢?

答案是肯定的,通過可變引數和關鍵字引數來接收不同的引數型別。

def setfunc(func):

return func(*args, *kwargs) # 再原樣傳回給被裝飾的函式

@setfunc

def show(name, age):

print(name,age)

show('tom',12)

通過類的定義也可以實現裝飾器形式。

在類中通過使用 __init__ 和 __call__方法來實現

class test(object):

# 通過初始化方法,將要被裝飾的函式傳進來並記錄下來

def __init__(self, func):

self.__func = func

# 重寫 __call__ 方法來實現裝飾內容

def __call__(self, *args, **kwargs):

self.__func(*args, **kwargs)

# 實際通過類的魔法方法call來實現

@test # --> show = test(show) show由原來引用函式,裝飾後變成引用test裝飾類的物件

def show():

pass

show() # 物件呼叫方法,實際上是呼叫魔法方法call,實現了裝飾器

類實現的裝飾器在裝飾函式後,原來的函式引用不在是函式,而是裝飾類的物件

python之裝飾器和閉包

在了解裝飾器之前,我們先來了解一下閉包,因為裝飾器的本質也是閉包。閉包 乙個函式定義中引用了函式外定義的變數,並且該函式可以在其定義環境外被執行,這樣乙個函式稱之為閉包。概念比較抽象,我們直接看 def outer func loc list def inner func name print lo...

python 裝飾器前之閉包和裝飾器

裝飾器 一,例如 vim yue7.py deffoo print fool foo 執行 root localhost python python yue7.py fool 二,要求 要在上述函式不改變函式呼叫方式的情況下增加 執行的時間。yue6.py import time defshow t...

python裝飾器和閉包

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