cookie和session區別,python裝飾器詳解-python裝飾器的詳細解析

 2023-11-18 阅读 28 评论 0

摘要:什么是裝飾器? python裝飾器(fuctional decorators)就是用于拓展原來函數功能的一種函數,目的是在不改變原函數名(或類名)的情況下,給函數增加新的功能。 cookie和session區別、這個函數的特殊之處在于它的返回值也是一個函數,這個

什么是裝飾器?

python裝飾器(fuctional decorators)就是用于拓展原來函數功能的一種函數,目的是在不改變原函數名(或類名)的情況下,給函數增加新的功能。

cookie和session區別、這個函數的特殊之處在于它的返回值也是一個函數,這個函數是內嵌"原"”函數的函數。

一般而言,我們要想拓展原來函數代碼,最直接的辦法就是侵入代碼里面修改,例如:

import time

python爬蟲教程,def f():

print("hello")

time.sleep(1)

print("world")

這是我們最原始的的一個函數,然后我們試圖記錄下這個函數執行的總時間,那最簡單的做法就是改動原來的代碼:

importtimedeff():

start_time=time.time()print("hello")

time.sleep(1)print("world")

end_time=time.time()

execution_time= (end_time - start_time)*1000

print("time is %d ms" %execution_time)

但是實際工作中,有些時候核心代碼并不可以直接去改,所以在不改動原代碼的情況下,我們可以再定義一個函數。(但是生效需要再次執行函數)

importtimedefdeco(func):

start_time=time.time()

f()

end_time=time.time()

execution_time= (end_time - start_time)*1000

print("time is %d ms" %execution_time)deff():print("hello")

time.sleep(1)print("world")if __name__ == '__main__':

deco(f)print("f.__name__ is",f.__name__)print()

這里我們定義了一個函數deco,它的參數是一個函數,然后給這個函數嵌入了計時功能。但是想要拓展這一千萬個函數功能,

就是要執行一千萬次deco()函數,所以這樣并不理想!接下來,我們可以試著用裝飾器來實現,先看看裝飾器最原始的面貌。

importtimedefdeco(f):defwrapper():

start_time=time.time()

f()

end_time=time.time()

execution_time= (end_time - start_time)*1000

print("time is %d ms" %execution_time )returnwrapper

@decodeff():print("hello")

time.sleep(1)print("world")if __name__ == '__main__':

f()

這里的deco函數就是最原始的裝飾器,它的參數是一個函數,然后返回值也是一個函數。

其中作為參數的這個函數f()就在返回函數wrapper()的內部執行。然后在函數f()前面加上@deco,

f()函數就相當于被注入了計時功能,現在只要調用f(),它就已經變身為"新的功能更多”的函數了,

(不需要重復執行原函數)。

擴展1:帶有固定參數的裝飾器

importtimedefdeco(f):defwrapper(a,b):

start_time=time.time()

f(a,b)

end_time=time.time()

execution_time= (end_time - start_time)*1000

print("time is %d ms" %execution_time)returnwrapper

@decodeff(a,b):print("be on")

time.sleep(1)print("result is %d" %(a+b))if __name__ == '__main__':

f(3,4)

擴展2:無固定參數的裝飾器

importtimedefdeco(f):def wrapper(*args, **kwargs):

start_time=time.time()

f(*args, **kwargs)

end_time=time.time()

execution_time_= (end_time - start_time)*1000

print("time is %d ms" %execution_time)returnwrapper

@decodeff(a,b):print("be on")

time.sleep(1)print("result is %d" %(a+b))

@decodeff2(a,b,c):print("be on")

time.sleep(1)print("result is %d" %(a+b+c))if __name__ == '__main__':

f2(3,4,5)

f(3,4)

擴展3:使用多個裝飾器,裝飾一個函數

importtimedefdeco01(f):def wrapper(*args, **kwargs):print("this is deco01")

start_time=time.time()

f(*args, **kwargs)

end_time=time.time()

execution_time= (end_time - start_time)*1000

print("time is %d ms" %execution_time)print("deco01 end here")returnwrapperdefdeco02(f):def wrapper(*args, **kwargs):print("this is deco02")

f(*args, **kwargs)print("deco02 end here")returnwrapper

@deco01

@deco02deff(a,b):print("be on")

time.sleep(1)print("result is %d" %(a+b))if __name__ == '__main__':

f(3,4)

'''

this is deco01

this is deco02

hello,here is a func for add :

result is 7

deco02 end here

time is 1003 ms

deco01 end here

'''

裝飾器調用順序

裝飾器是可以疊加使用的,那么使用裝飾器以后代碼是啥順序呢?

對于Python中的”@”語法糖,裝飾器的調用順序與使用 @ 語法糖聲明的順序相反。

在這個例子中,”f(3, 4) = deco01(deco02(f(3, 4)))”。

Python內置裝飾器

在Python中有三個內置的裝飾器,都是跟class相關的:staticmethod、classmethod 和property。

staticmethod 是類靜態方法,其跟成員方法的區別是沒有 self 參數,并且可以在類不進行實例化的情況下調用

classmethod 與成員方法的區別在于所接收的第一個參數不是 self (類實例的指針),而是cls(當前類的具體類型)

property 是屬性的意思,表示可以通過通過類實例直接訪問的信息

對于staticmethod和classmethod這里就不介紹了,通過一個例子看看property。

aa213e02gw1ewkmp5xioqj20ij09m3zr.jpg

注意,對于Python新式類(new-style class),如果將上面的 "@var.setter” 裝飾器所裝飾的成員函數去掉,則Foo.var 屬性為只讀屬性,使用 "foo.var = "var 2′” 進行賦值時會拋出異常。但是,對于Python classic class,所聲明的屬性不是 read-only的,所以即使去掉”@var.setter”裝飾器也不會報錯。

總結

本文介紹了Python裝飾器的一些使用,裝飾器的代碼還是比較容易理解的。只要通過一些例子進行實際操作一下,就很容易理解了。

參考鏈接:https://blog.csdn.net/xiangxianghehe/article/details/77170585

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/176930.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息