python之闭包,装饰器
生活随笔
收集整理的這篇文章主要介紹了
python之闭包,装饰器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 函數對象 :相當于變量名
- 函數對象的作用:
- 1. 可以引用
- 2. 可以作為函數的返回值
- 3. 可以作為容器的元素
- 4. 可以作為函數的參數
- 函數對象的作用:
- 閉包
- 定義:
- 如果在一個函數的內部定義了另一個函數,外部的我們叫他外函數,內部的我們叫他內函數。那閉包就是,在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用。這樣就構成了一個閉包
- ps:
- 一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。但是閉包是一種特殊情況,如果外函數在結束的時候發現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給內部函數,然后自己結束。
- 閉包的意義:
- 返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得該函數無論在何處調用,優先使用自己外層包裹的作用域
- 定義:
- 裝飾器
- 本質:裝飾器 = 函數。它的本質就是函數
- 作用:給原函數增加新的功能
- 原則:
- 1. 不能改變被裝飾的函數的調用方式
- 2. 裝飾器不能修改裝飾函數的源代碼
- 實現裝飾器的知識儲備:
- 1. 函數即“變量”
- 2. 高階函數。即一個函數可以作為另外一個函數的參數,這種函數就稱之為高階函數。
- 3. 嵌套函數。即定義一個函數時,在其函數體中又定義了一個函數,這個函數稱之為嵌套函數。
- 裝飾器的模板語法
- 裝飾器的弊端:
函數對象 :相當于變量名
函數對象的作用:
1. 可以引用
def f1():print("from f1")a = f1 a()''' from f1'''2. 可以作為函數的返回值
def f1():print("from f1")def f2():return f1a = f2() a()''' from f1 '''3. 可以作為容器的元素
def f1():print("from f1") a = [1,2,3,4,5,f1]4. 可以作為函數的參數
def f1():print("from f1")def f2(func):func()f2(f1)''' from f1 '''閉包
定義:
如果在一個函數的內部定義了另一個函數,外部的我們叫他外函數,內部的我們叫他內函數。那閉包就是,在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用。這樣就構成了一個閉包
ps:
一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。但是閉包是一種特殊情況,如果外函數在結束的時候發現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給內部函數,然后自己結束。
閉包的意義:
返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得該函數無論在何處調用,優先使用自己外層包裹的作用域
# 閉包 def test_plf(x):def test_lt():print(x)return test_ltf1 = test_plf(8) f1()# 閉包的應用 import requests def req(url):def test_plf():request = requests.get(url)data = request.status_codeprint(data)return test_plfbaidu = req("https://www.baidu.com") baidu() baidu() baidu() boke = req("https://www.cnblogs.com/plf-Jack/") boke() boke() boke()# 使用普通函數進行對比 import requests def req(url):content = requests.get(url)data = content.status_codeprint(data)req("https://www.baidu.com") req("https://www.baidu.com") req("https://www.baidu.com") req("https://www.cnblogs.com/plf-Jack/") req("https://www.cnblogs.com/plf-Jack/") req("https://www.cnblogs.com/plf-Jack/")'''總結:相比使用普通函數和使用閉包函數實現相同業務邏輯1. 閉包在調用上要比普通函數要簡單2. 閉包相對于普通函數的定義,邏輯上難度要大一些3. 閉包主要應用于延遲計算,爬蟲領域 '''裝飾器
本質:裝飾器 = 函數。它的本質就是函數
作用:給原函數增加新的功能
原則:
1. 不能改變被裝飾的函數的調用方式
2. 裝飾器不能修改裝飾函數的源代碼
實現裝飾器的知識儲備:
1. 函數即“變量”
2. 高階函數。即一個函數可以作為另外一個函數的參數,這種函數就稱之為高階函數。
3. 嵌套函數。即定義一個函數時,在其函數體中又定義了一個函數,這個函數稱之為嵌套函數。
裝飾器的模板語法
def deco(func):def wrapper(*args,**kwargs):res = func(*args,**kwargs)return resreturn wrapper無參裝飾器
import time def test_lt(func):def warpper():start_time = time.time()func()end_time = time.time()print("你睡了%s秒"%(end_time-start_time))return warpper@test_lt # 語法糖,即簡潔。它等同于 test_plf = test_lt(test_plf) def test_plf():time.sleep(1)print("我睡了多長時間")返回值裝飾器
import timedef test_lt(func):def warpper():start_time = time.time()res = func()end_time = time.time()print("睡了%s秒"%(end_time-start_time))return resreturn warpper@test_lt #test_plf = test_lt(test_plf) def test_plf():time.sleep(1)print("我睡了多長時間")return 123a = test_plf() print("返回值為%d"%a)有參裝飾器
dic = {"PLF":'123'} is_login = False def auth(test_type='file'):def login_desc(func):def wrepper():if test_type == "file":global is_login # 聲明的是全局變量的is_loginif not is_login:user_name = input("請輸入賬號>>>")user_pwd = input("請輸入密碼>>>")if dic.get(user_name) != user_pwd:print("輸入錯誤")returnprint("密碼輸入正確")is_login = Truefunc()returnfunc()elif test_type == "txt":print("文件類型不正確")else:print("你走開")return wrepperreturn login_desc@auth(test_type="file") def go_shopping():print("購物")@auth(test_type="txt") def pay():print("支付")@auth(test_type="makeDown") def see_list():print("查看清單")go_shopping() pay() see_list()裝飾器的弊端:
import timedef test_lt(func):def warpper():start_time = time.time()res = func()end_time = time.time()print("睡了%s秒"%(end_time-start_time))return resreturn warpper@test_lt #test_plf = test_lt(test_plf) def test_plf():time.sleep(1)print("我睡了多長時間")return 123print(test_plf.__name__)''' warpper ''''''總結:1. 目標函數(test_plf)是一個函數對象,它里米那有自己的屬性,如函數名__name__,說明文檔__doc__等等。但如果目標函數被裝飾器裝飾之后,我們在調用目標函數的__name__會發現,本來我們想要的test_plf名字,結果打印出來了warpper。這種情況確實不出乎意料,因為test_plf被裝飾之后確實存的就是warpper了,我們對test_plf的操作實際上都是對inner的操作.2. 以上的操作帶來了使用的不一致性。如果我們能把本來目標函數各種方法覆蓋給test_plf函數就好了。這里我們可以用functools包里的工具來實現。這里暫不做解釋,有興趣的同學先去百度一下。 '''參考博客:https://www.cnblogs.com/Lin-Yi/p/7306235.html
轉載于:https://www.cnblogs.com/plf-Jack/p/10957486.html
總結
以上是生活随笔為你收集整理的python之闭包,装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ##安装MySql数据库并解决如果安装出
- 下一篇: 认识React框架