Python中函數(shù)的閉包和裝飾器示例詳解
1. python的內(nèi)部函數(shù)示例
# 定義一個(gè)外部函數(shù) def func_out(num1): # 定義一個(gè)內(nèi)部函數(shù) def func_inner(num2): # 內(nèi)部函數(shù)使用了外部函數(shù)的變量(num1) result = num1 + num2 print("結(jié)果是:", result) # 外部函數(shù)返回了內(nèi)部函數(shù),這里返回的內(nèi)部函數(shù)就是閉包 return func_inner # 創(chuàng)建閉包實(shí)例,返回內(nèi)部函數(shù) # 此時(shí)的f是內(nèi)部函數(shù) f = func_out(100) # 執(zhí)行閉包 f(2) f(3) """ f接收到func_out的返回值 f = func_inner f() = func_inner() """
示例2:
def config_name(name): def say_hello(info): print(f"{name}: {info}") return say_hello if __name__ == '__main__': # 創(chuàng)建閉包實(shí)例 tom = config_name("tom") tom("What did you have for lunch ?") jarry = config_name("jarry") jarry("I had vegetables and beef.") """ tom: What did you have for lunch ? jarry: I had vegetables and beef. """
調(diào)用閉包相當(dāng)于調(diào)用內(nèi)部函數(shù)
閉包的構(gòu)成條件
1. 在函數(shù)嵌套的前提下
2. 內(nèi)部函數(shù)使用了外部函數(shù)的變量(還包括外部函數(shù)的參數(shù))
3. 外部函數(shù)返回了內(nèi)部函數(shù)結(jié)論:閉包可以對外部函數(shù)的變量進(jìn)行保存
2. 閉包內(nèi)修改外部變量
def func_out(num1): def func_inner(num2): # 此時(shí)的num1屬于內(nèi)部函數(shù),不是外部函數(shù)的num1 num1 = num2 + 100 print("改前:num1 =",num1) # 調(diào)用內(nèi)部函數(shù)修改num1的值 func_inner(200) # 調(diào)用方法改變num1的值 print("改后:num1 =",num1) return func_inner # 實(shí)例化閉包 f = func_out(10) """ 改前:num1 = 10 改后:num1 = 10 """
def func_out(num1): def func_inner(num2): # 此時(shí)的num1是外部函數(shù)變量 nonlocal num1 num1 = num2 + 100 print("改前:num1 =",num1) # 調(diào)用內(nèi)部函數(shù)修改num1的值 func_inner(200) # 調(diào)用方法改變num1的值 print("改后:num1 =",num1) return func_inner # 實(shí)例化閉包 f = func_out(10) # f(10) --> 這是調(diào)用閉包(內(nèi)部函數(shù)),這里沒有調(diào)用閉包,只是創(chuàng)建了閉包 """ 改前:num1 = 10 改后:num1 = 300 """
修改閉包使用的外部函數(shù)變量使用nonlocal關(guān)鍵字修飾
3. 裝飾器:在不改變原有函數(shù)的源代碼的情況下,給函數(shù)添加功能
1.不修改原有函數(shù)的源代碼
2. 給已有的函數(shù)添加額外的功能符合開發(fā)中的封閉開放原則
# 1. 定義一個(gè)裝飾器(一個(gè)閉包, 一個(gè)內(nèi)部函數(shù)) def check(fn): # fn是comment函數(shù) def inner(): print("請先登錄") fn() return inner # 2. 需要被裝飾的函數(shù) def comment(): print("發(fā)表評論") # 3. 使用裝飾器裝飾函數(shù)(增加一個(gè)登錄功能) # 左側(cè)的comment函數(shù)已經(jīng)變成了inner()函數(shù) comment = check(comment) comment() """ 請先登錄 發(fā)表評論 """
裝飾器就是把一個(gè)函數(shù)當(dāng)作參數(shù)傳遞給閉包中的外部函數(shù),同時(shí)在內(nèi)部函數(shù)中使用這個(gè)函數(shù),并給它添加新的功能
def check(fn): def inner(): print("請先登錄") fn() return inner # 解釋器遇到@check,會執(zhí)行comment = check(comment) @check def comment(): print("發(fā)表評論") comment() """ 請先登錄 發(fā)表評論 """
4.修飾帶參數(shù)的函數(shù)
"""裝飾帶參數(shù)的函數(shù)""" def loggin(fn): def inner(a,b): print("請先登錄") fn(a,b) return inner def sum_num(a,b): result = a+b print(result) # sum_num = inner sum_num = loggin(sum_num) sum_num(1,2) """ 請先登錄 3 """
"""裝飾帶參數(shù)的函數(shù)""" def loggin(fn): def inner(a,b): print("請先登錄") fn(a,b) return inner # sum_num = inner, sum_sum = loggin(sum_num) @loggin def sum_num(a,b): result = a + b print(result) sum_num(1,2) """ 請先登錄 3 """
5. 裝飾帶有返回值的函數(shù)
"""裝飾帶返回值的函數(shù)""" def loggin(fn): def inner(a,b): print("請先登錄") return fn(a,b) return inner @loggin def sum_num(a,b): result = a+b return result ans = sum_num(1,2) print("ans = ",ans) """ 請先登錄 ans = 3 """
6. 修飾不定長參數(shù)的函數(shù)
def loggin(fn): def inner(*args): print("請先登錄") return fn(*args) return inner @loggin def sum_args(*args): ans = sum(args) return ans ans = sum_args(1,2,3,4,5) print("ans = ",ans) """ 請先登錄 ans = 15 """
7. 多個(gè)裝飾器的使用
def check1(fn): def inner1(): print("登錄驗(yàn)證1") fn() return inner1 def check2(fn): def inner2(): print("登錄驗(yàn)證2") fn() return inner2 @check2 @check1 def comment(): print("發(fā)表評論") comment() """ 登錄驗(yàn)證2 登錄驗(yàn)證1 發(fā)表評論 """
8. 帶有參數(shù)的裝飾器
""" 帶參數(shù)的裝飾器,正確案例 """ def loggin(flag): def decorator(fn): def inner(num1, num2): # 判斷流程 if flag == "+": print("--正在努力加法計(jì)算--") elif flag == "-": print("--正在努力減法計(jì)算--") ant = fn (num1,num2) return ant return inner return decorator # 被帶有參數(shù)的裝飾器飾的函數(shù) @loggin("+") # 1. loggin("+") 2. @decorator起到裝飾器的功能了 def sum_num(a, b): res = a + b return res result = sum_num(1,3) print("result = ",result)
帶參數(shù)的裝飾器
1. 裝飾器的外部函數(shù)只接受一個(gè)參數(shù) -- 被裝飾的函數(shù)
2. 需要給裝飾器參數(shù)需要在裝飾器外部再增加一個(gè)函數(shù)
9. call方法
class Check(object): def __call__(self,*args,**kwargs): print("請先登錄") c1 = Check() c1() """請先登錄"""
10. 類裝飾器
class Check(object): def __init__(self,fn): self._fn = fn def __call__(self,*args,**kwargs): print("請先登錄") self._fn() @Check # comment = Check(comment) def comment(): print("發(fā)表評論") comment() """ 請先登錄 發(fā)表評論 """
11. property 裝飾器方式
class Person(object): def __init__(self) -> None: self.__age = 0 @property def age(self): return self.__age @age.setter def age(self, new_age): self.__age = new_age p = Person() print(p.age) p.age = 100 print(p.age)
12. property類屬性方式
class Person(object) : def __init__(self) -> None: self.__age = 0 def get_age(self): return self.__age def set_age(self, new_age): if new_age >= 150: print("年齡錯(cuò)誤") else: self.__age = new_age age = property(get_age, set_age) p = Person() print(p.age) p.age = 60 print( p.age )
總結(jié)
到此這篇關(guān)于Python中函數(shù)的閉包和裝飾器的文章就介紹到這了,更多相關(guān)Python函數(shù)的閉包和裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 3.8新特征之a(chǎn)syncio REPL
我最近都在寫一些Python 3.8的新功能介紹的文章,在自己的項(xiàng)目中也在提前體驗(yàn)新的Python版本。這篇文章主要介紹了Python 3.8新特征之a(chǎn)syncio REPL,需要的朋友可以參考下2019-05-05簡單實(shí)現(xiàn)python收發(fā)郵件功能
這篇文章主要教大家如何簡單實(shí)現(xiàn)python收發(fā)郵件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Pycharm2020.1安裝無法啟動問題即設(shè)置中文插件的方法
這篇文章主要介紹了Pycharm2020.1安裝無法啟動問題即設(shè)置中文插件的操作方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-08-08python 已知一個(gè)字符,在一個(gè)list中找出近似值或相似值實(shí)現(xiàn)模糊匹配
今天小編就為大家分享一篇python 已知一個(gè)字符,在一個(gè)list中找出近似值或相似值實(shí)現(xiàn)模糊匹配,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02opencv矩形輪廓頂點(diǎn)的具體位置確定的兩種實(shí)現(xiàn)方法
本文主要介紹了opencv矩形輪廓頂點(diǎn)的具體位置確定,通過線性規(guī)劃和最小面積矩兩種方法定位紙張四個(gè)頂點(diǎn),具有一定的參考價(jià)值,感興趣的可以了解一下2025-07-07