Python中閉包和裝飾器的學(xué)習(xí)攻略
一、閉包
(1)作用域
學(xué)習(xí)閉包前先要回顧一下作用域的知識:作用域一般分為全局作用域和局部作用域,對應(yīng)使用的就是全局變量和局部變量;
值得注意的是在局部作用域中可以訪問全局變量,而全局作用域中是不能訪問局部變量的
原因:Python的底層存在一個內(nèi)存回收空間,用于加快計算機(jī)的運(yùn)行;變量同樣需要占用內(nèi)存,當(dāng)局部作用域所代表的函數(shù)在運(yùn)行過后,其內(nèi)部的變量和程序會被Python當(dāng)作已經(jīng)使用過的內(nèi)存進(jìn)行回收
既然是范圍方面的程序就會有解決的方法,當(dāng)程序中需要在全局作用域?qū)崿F(xiàn)對局部變量的訪問時,就要用到閉包了
(2)閉包的含義
閉包:在函數(shù)嵌套的前提下,內(nèi)部的函數(shù)使用了外部函數(shù)的變量,外部函數(shù)又返回了內(nèi)部函數(shù),這時這個內(nèi)部函數(shù)就是閉包
(3)閉包的構(gòu)成
如何區(qū)分一個程序是否存在閉包,閉包一般有三步構(gòu)成的條件:
1、存在函數(shù)的嵌套
2、有內(nèi)部函數(shù)的對于外部函數(shù)的引用
3、有外部函數(shù)對內(nèi)部函數(shù)進(jìn)行返回(即return)
這里需要注意的是,閉包引用了外部函數(shù)的變量,所以外部函數(shù)的變量在運(yùn)行完外部函數(shù)之后其內(nèi)存并沒有得到釋放,會消耗內(nèi)存
經(jīng)典閉包的構(gòu)成例子:
def outer():
num = 20
def inner():
print(num)
return inner
f = outer()
f()
1、存在嵌套函數(shù):outer是外部函數(shù),inner是內(nèi)部函數(shù)
2、內(nèi)部函數(shù)inner引用了外部函數(shù)outer中的自由變量num
3、外部函數(shù)outer返回了內(nèi)部函數(shù)inner的引用
4、當(dāng)outer()執(zhí)行完畢后,返回的inner函數(shù)依然可以訪問并保留對變量num的綁定,形成閉包
(4)閉包實現(xiàn)對外部變量的修改
這里要引用一個新的關(guān)鍵詞nonlocal;它是用于聲明函數(shù)內(nèi)部修改函數(shù)外部的變量,這個變量不是全局變量
它和global關(guān)鍵字不同就在于global在函數(shù)內(nèi)部聲明變量,但這個變量是全局變量
二者在實際的使用是相似的,只是使用的場景和作用不同
閉包實現(xiàn)修改的案例:
def outer():
res = 20
def inner(num):
nonlocal res
res += num
print(res)
return inner
f = outer()
f(1)
f(2)
res作為外部函數(shù)的局部變量,num作為內(nèi)部函數(shù)的變量;res+=num就能直接修改res變量,再打印res引用外部函數(shù)變量,outer()再返回內(nèi)部函數(shù)inner形成閉包,最后全局使用外部函數(shù),可以看到這時的f(1)和f(2)中res發(fā)生了變化,而且是遞進(jìn)改變的

二、裝飾器
(1)什么是裝飾器
裝飾器:在不改變現(xiàn)有函數(shù)代碼和函數(shù)調(diào)用的前提下,實現(xiàn)給函數(shù)增加額外的功能
裝飾器本質(zhì)上也是一個閉包函數(shù)
(2)裝飾器的定義
def register(fn):
def inner():
print('開始注冊')
fn()
return inner
@register
def login():
print('登錄成功')
login()register就是一個裝飾器函數(shù),接收函數(shù)fn為參數(shù);
@register語法就是將裝飾器應(yīng)用于login函數(shù)中
調(diào)用login時其實是調(diào)用了裝飾器register中的inner函數(shù),所以先打印開始注冊,然后打印登錄成功
效果如下:

(3)裝飾器的簡單使用
import time
def get_time(fn):
def inner():
start = time.time()
fn()
end = time.time()
print(f"執(zhí)行時間為:{end - start}s")
return inner
@get_time
def demo():
for i in range(1000000):
print(i)
demo()這個裝飾器功能用于可以計算下面demo()函數(shù)運(yùn)行完的執(zhí)行時間,感興趣可以深入了解一下
(4)裝飾器的形式(了解即可)
帶參數(shù)的裝飾器
def log(fn):
def inner(*args, **kwargs):
fn(*args, **kwargs)
return inner
@log
def demo_1(*args, **kwargs):
res = 0
for i in args:
res += i
for i in kwargs.values():
res += i
print(res)
demo_1(10, 20, a=30, b=40)
關(guān)于不定長參數(shù),在之前的Python學(xué)習(xí)中已經(jīng)了解了,這里不多闡述
帶返回的裝飾器
def log(fn):
def inner(*args, **kwargs):
return fn(*args, **kwargs)
return inner
@log
def demo_1(a, b):
res = a - b
return res
print(demo_1(20,10))
通用裝飾器
def log(fn):
def inner(*args, **kwargs):
return fn(*args, **kwargs)
return inner
@log
def demo_1(a, b):
res = a + b
return res
print(demo_1(20,10))
@log
def demo_2(a, b, c):
res = a + b + c
return res
print(demo_2(20,10,5))
一般裝飾器形式以這個為準(zhǔn)
可以看到裝飾器的形式一般都大差不差,按照閉包的形式遵循一定的規(guī)則,然后調(diào)用函數(shù)即可
(5)裝飾器的擴(kuò)展(了解)
使用裝飾器傳遞參數(shù)
基本語法:
def 裝飾器名(形參):
#代碼
@裝飾器名('參數(shù)')
def 被裝飾函數(shù)():
#代碼
代碼:
def log(flag):
def f1(fn):
def inner(*args, **kwargs):
if flag == '+':
print("正進(jìn)行加法運(yùn)算")
elif flag == '-':
print("正進(jìn)行減法運(yùn)算")
return fn(*args, **kwargs)
return inner
return f1
@log('+')
def demo_1(a, b):
res = a + b
return res
@log('-')
def demo_2(a, b):
res = a - b
return res
print(demo_1(20,10))
print(demo_2(100,10))效果如下:

類裝飾器
基本語法:
class 類裝飾器():
#代碼
@類裝飾器名稱
def 函數(shù)():
#代碼代碼:
class Check():
def __init__(self, fn):
self.__fn = fn
def __call__(self, *args, **kwargs):
print("開始檢查")
self.__fn(*args, **kwargs)
@Check
def comment():
print("正在檢查")
comment()效果如下:

其實就是在裝飾器的基礎(chǔ)上用到了類的方法
總結(jié)
到此這篇關(guān)于Python中閉包和裝飾器學(xué)習(xí)攻略的文章就介紹到這了,更多相關(guān)Python閉包和裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
20個Python中正則表達(dá)式的應(yīng)用與技巧小結(jié)
正則表達(dá)式是一種用來匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,本文我們將探討?Python?中?re?模塊的應(yīng)用和一些技巧,希望可以幫助您更好地理解和利用正則表達(dá)式2024-04-04
Python使用itcaht庫實現(xiàn)微信自動收發(fā)消息功能
這篇文章主要介紹了Python使用itcaht庫實現(xiàn)微信自動收發(fā)消息功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
Python基于更相減損術(shù)實現(xiàn)求解最大公約數(shù)的方法
這篇文章主要介紹了Python基于更相減損術(shù)實現(xiàn)求解最大公約數(shù)的方法,簡單說明了更相減損術(shù)的概念、原理并結(jié)合Python實例形式分析了基于更相減損術(shù)實現(xiàn)求解最大公約數(shù)的相關(guān)操作技巧與注意事項,需要的朋友可以參考下2018-04-04

