日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python装饰器_Python基础-装饰器

發布時間:2025/3/15 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python装饰器_Python基础-装饰器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:Zarten知乎專欄:Python基礎深入詳解知乎ID: Zarten簡介: 互聯網一線工作者,尊重原創并歡迎評論留言指出不足之處,也希望多些關注和點贊是給作者最好的鼓勵 !

概述

裝飾器其實就是一個函數,返回值是一個函數對象,它可以讓其他函數在不需要做任何代碼改動的前提下增加額外功能,比如:日志功能、性能測試、緩存、事務處理、權限校驗等。

為了理解裝飾器,我們要先理解一個概念,即:python里面一切皆對象,包括函數。

函數裝飾器詳解

最簡單的裝飾器

def my_decorator(f):return f

這個裝飾器什么也沒做,返回原函數對象。

裝飾器的使用

def my_decorator(f):return f@my_decorator def fun():print('zarten')fun()

上面代碼等價于:

def my_decorator(f):return fdef fun():print('zarten')fun = my_decorator(fun) fun()

一般使用第一種方式,python中特有的裝飾器語法,更加簡潔。

裝飾器返回另外一個函數

裝飾器通常都是返回另外一個函數,而不是原函數本身

def my_decorator(f):def other_fun():print('other_fun')return other_fun@my_decorator def fun():print('zarten')fun() print(fun)

調用fun()函數,其實是運行裝飾器里面的other_fun()函數。從輸出結果也可看到,fun()函數現在是other_fun()函數的引用。

從輸出結果可以看到,并沒有執行fun()函數內的代碼,這是因為在裝飾器內部執行了other_fun()函數,但并沒有在內部執行fun()函數,所以一般在裝飾器傳入參數,這個參數是被裝飾的函數對象,都會在裝飾器內部調用并返回其結果

def my_decorator(f):def other_fun():print('other_fun')return f()return other_fun@my_decorator def fun():print('zarten')fun() print(fun)

functools.wraps的作用

我們知道,執行fun()函數,實際上是執行了裝飾器里面的other_fun()函數,并在內部返回了原函數。但這樣有個缺點是:原函數的一些元信息發生了改變,如docstring、__name__、參數列表等。如下代碼所示:

def my_decorator(f):def other_fun():print('other_fun')return f()return other_fun@my_decorator def fun():print('zarten')print('fun name:', fun.__name__)

為了防止元信息改變,python引入了functools.wraps,用法如下

from functools import wraps def my_decorator(f):@wraps(f)def other_fun():print('other_fun')return f()return other_fun@my_decorator def fun():print('zarten')print('fun name:', fun.__name__)

一個完整簡單的日志打印裝飾器

from functools import wrapsdef my_decorator(f):@wraps(f)def other_fun(*args, **kwargs):print('%s in running' % f.__name__)return f(*args, **kwargs)return other_fun@my_decorator def fun():print('zarten')fun()

帶參數的裝飾器

裝飾器是把被裝飾函數作為第一個參數傳進去,若裝飾器帶有參數時,怎么接收其他額外的參數呢?

方法是:將額外的參數作為第一個參數傳進去,然后返回一個函數對象,這個函數的參數才是被裝飾函數的對象

from functools import wrapsdef my_decorator(zhihu_id= 'zarten'):def decorator(f):@wraps(f)def other_fun(*args, **kwargs):print('%s in running.name is %s' % (f.__name__, zhihu_id))return f(*args, **kwargs)return other_funreturn decorator@my_decorator('zarten_2') def fun():print('zarten')fun()

從上面代碼可以看到,裝飾器使用的默認參數,若裝飾器不傳遞任何參數時,也需要使用空括號,如@my_decorator()

類裝飾器詳解

類裝飾器,也就是說裝飾器是一個類了,而不是一個函數了。類裝飾器和函數裝飾器非常類似。

可以利用類的特殊方法__call__()來實現,實現此特殊方法后,類對象可以像函數一樣調用。PS:若對python中的常用特殊方法不了解的,可以查看我之前寫的文章,點這里。

類裝飾器的實現

class Decorator():def __init__(self, f):self.f = fdef __call__(self, *args, **kwargs):print('%s in running' % self.f.__name__)self.f(*args, **kwargs)

使用類裝飾器

使用類裝飾器跟使用函數裝飾也是非常的類似

@Decorator def fun():print('zarten')fun()

此時被裝飾的函數對象作為裝飾器類的參數傳入,返回一個類裝飾器的對象,由于裝飾器類里實現了__call__()的特殊方法,固可以直接調用這個對象。

若不使用@Decorator語法糖,上面代碼等價于:

def fun():print('zarten')fun = Decorator(fun) fun()

完整代碼如下:

class Decorator():def __init__(self, f):self.f = fdef __call__(self, *args, **kwargs):print('%s in running' % self.f.__name__)self.f(*args, **kwargs)@Decorator def fun():print('zarten')fun()

總結

以上是生活随笔為你收集整理的python装饰器_Python基础-装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。