中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python裝飾器帶參數的使用方式

發布時間:2020-04-28 09:50:09 來源:億速云 閱讀:312 作者:小新 欄目:編程語言

今天小編給大家分享的是python裝飾器帶參數的使用方式,相信很多人都不太了解,為了讓大家更加了解python裝飾器,所以給大家總結了以下內容,一起往下看吧。一定會有所收獲的哦。

python裝飾器詳解

python裝飾器的詳細解析

什么是裝飾器?

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

這個函數的特殊之處在于它的返回值也是一個函數,這個函數是內嵌“原“”函數的函數。

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

import time
def f():
    print("hello")
    time.sleep(1)
    print("world")  

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

import time
def f():
    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)

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

import time
def deco(func):
    start_time = time.time()
    f()
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    deco(f)
    print("f.__name__ is",f.__name__)
    print()

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

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

import time
def deco(f):
    def wrapper():
        start_time = time.time()
        f()
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time )
    return wrapper
@deco
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    f()

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

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

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

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

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

import time
def deco(f):
    def wrapper(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)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
if __name__ == '__main__':
    f(3,4)

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

import time
def deco(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)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
@deco
def f2(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:使用多個裝飾器,裝飾一個函數

import time
def deco01(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")
    return wrapper
def deco02(f):
    def wrapper(*args, **kwargs):
        print("this is deco02")
        f(*args, **kwargs)
        print("deco02 end here")
    return wrapper
@deco01
@deco02
def f(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。

python裝飾器帶參數的使用方式

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

總結

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

關于python裝飾器帶參數的使用方式就分享到這里了,希望以上內容可以對大家有一定的參考價值,可以學以致用。如果喜歡本篇文章,不妨把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鸡西市| 黄平县| 南木林县| 政和县| 延吉市| 大足县| 比如县| 青冈县| 山西省| 东兰县| 闽侯县| 霍林郭勒市| 安康市| 灵璧县| 光山县| 仲巴县| 青铜峡市| 齐河县| 朝阳区| 蒙阴县| 聂荣县| 额济纳旗| 依安县| 齐齐哈尔市| 衡阳市| 平武县| 建始县| 合肥市| 新巴尔虎左旗| 五峰| 巴南区| 郸城县| 临汾市| 县级市| 重庆市| 惠来县| 棋牌| 太白县| 郧西县| 东乌珠穆沁旗| 澜沧|