日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

python 裝飾器的使用與要點

瀏覽:27日期:2022-06-18 15:04:07
目錄一、裝飾器使用場景二、為什么需要裝飾器1、先來看一個簡單例子:2、增加需求3、又有需求三、基礎裝飾器入門1、裝飾器語法糖2、對帶參數的函數進行裝飾3、函數參數數量不確定4、裝飾器帶參數5、functools.wraps6、實現帶參數和不帶參數的裝飾器自適應三、類裝飾器1、類裝飾器 2、繼承擴展類裝飾器一、裝飾器使用場景

經常用于有切面需求的場景,比如:插入日志、性能測試、事務處理、緩存、權限校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量與函數功能本身無關的雷同代碼并繼續重用。

概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。

二、為什么需要裝飾器1、先來看一個簡單例子:

def foo():print(’i am foo’)2、增加需求

現在有一個新的需求,希望可以記錄下函數的執行日志,于是在代碼中添加日志代碼:

def foo(): print(’i am foo’) print('foo is running')3、又有需求

假設現在有100個函數需要增加這個需求,并且后續可能還要對這一百個函數都增加執行前打印日志的需求,怎么辦?還一個個改嗎?

當然不了,這樣會造成大量雷同的代碼,為了減少重復寫代碼,我們可以這樣做,重新定義一個函數:專門處理日志 ,日志處理完之后再執行真正的業務代碼。

def use_logging(func): print('%s is running' % func.__name__) func()def bar(): print(’i am bar’)use_logging(bar)運行結果:#bar is running#i am bar

函數use_logging就是裝飾器,它把執行真正業務方法的func包裹在函數里面,看起來像bar被use_logging裝飾了。在這個例子中,函數進入和退出時 ,被稱為一個橫切面(Aspect),這種編程方式被稱為面向切面的編程(Aspect-Oriented Programming)。

通過以上use_logging函數我們增加了日志功能,不管以后有多少函數需要增加日志或者修改日志的格式我們只需要修改use_logging函數,并執行use_logging(被裝飾的函數)就達到了我們想要的效果。

def use_logging(func): print('%s is running' % func.__name__) return func@use_loggingdef bar(): print(’i am bar’)bar()三、基礎裝飾器入門1、裝飾器語法糖

python提供了@符號作為裝飾器的語法糖,使我們更方便的應用裝飾函數;但使用語法糖要求裝飾函數必須return一個函數對象。因此我們將上面的func函數使用內嵌函數包裹并return。

裝飾器相當于執行了裝飾函數use_loggin后又返回被裝飾函數bar,因此bar()被調用的時候相當于執行了兩個函數。等價于use_logging(bar)()

def use_logging(func): def _deco():print('%s is running' % func.__name__)func() return _deco@use_loggingdef bar(): print(’i am bar’)bar()2、對帶參數的函數進行裝飾

現在我們的參數需要傳入兩個參數并計算值,因此我們需要對內層函數進行改動傳入我們的兩個參數a和b,等價于use_logging(bar)(1,2)

def use_logging(func): def _deco(a,b):print('%s is running' % func.__name__)func(a,b) return _deco@use_loggingdef bar(a,b): print(’i am bar:%s’%(a+b))bar(1,2)

我們裝飾的函數可能參數的個數和類型都不一樣,每一次我們都需要對裝飾器做修改嗎?這樣做當然是不科學的,因此我們使用python的變長參數*args和**kwargs來解決我們的參數問題。

3、函數參數數量不確定

不帶參數裝飾器版本,這個格式適用于不帶參數的裝飾器。

經過以下修改,我們已經適應了各種長度和類型的參數。這個版本的裝飾器可以裝飾任意類型的無參數函數。

def use_logging(func): def _deco(*args,**kwargs):print('%s is running' % func.__name__)func(*args,**kwargs) return _deco@use_loggingdef bar(a,b): print(’i am bar:%s’%(a+b))@use_loggingdef foo(a,b,c): print(’i am bar:%s’%(a+b+c))bar(1,2)foo(1,2,3)4、裝飾器帶參數

帶參數的裝飾器,這個格式適用于帶參數的裝飾器。

某些情況我們需要讓裝飾器帶上參數,那就需要編寫一個返回一個裝飾器的高階函數,寫出來會更復雜。比如:

#! /usr/bin/env python# -*- coding:utf-8 -*-# __author__ = 'TKQ'def use_logging(level): def _deco(func):def __deco(*args, **kwargs): if level == 'warn':print '%s is running' % func.__name__ return func(*args, **kwargs)return __deco return _deco@use_logging(level='warn')def bar(a,b): print(’i am bar:%s’%(a+b))bar(1,3)# 等價于use_logging(level='warn')(bar)(1,3)5、functools.wraps

使用裝飾器極大地復用了代碼,但是他有一個缺點就是原函數的元信息不見了,比如函數的docstring、__name__、參數列表,先看例子:

def use_logging(func): def _deco(*args,**kwargs):print('%s is running' % func.__name__)func(*args,**kwargs) return _deco@use_loggingdef bar(): print(’i am bar’) print(bar.__name__)bar()#bar is running#i am bar#_deco#函數名變為_deco而不是bar,這個情況在使用反射的特性的時候就會造成問題。因此引入了functools.wraps解決這個問題。

使用functools.wraps:

import functoolsdef use_logging(func): @functools.wraps(func) def _deco(*args,**kwargs):print('%s is running' % func.__name__)func(*args,**kwargs) return _deco@use_loggingdef bar(): print(’i am bar’) print(bar.__name__)bar()#result:#bar is running#i am bar#bar ,這個結果是我們想要的。OK啦!6、實現帶參數和不帶參數的裝飾器自適應

import functoolsdef use_logging(arg): if callable(arg):#判斷參入的參數是否是函數,不帶參數的裝飾器調用這個分支@functools.wraps(arg)def _deco(*args,**kwargs): print('%s is running' % arg.__name__) arg(*args,**kwargs)return _deco else:#帶參數的裝飾器調用這個分支def _deco(func): @functools.wraps(func) def __deco(*args, **kwargs):if arg == 'warn': print 'warn%s is running' % func.__name__return func(*args, **kwargs) return __decoreturn _deco@use_logging('warn')# @use_loggingdef bar(): print(’i am bar’) print(bar.__name__)bar()三、類裝飾器

使用類裝飾器可以實現帶參數裝飾器的效果,但實現的更加優雅簡潔,而且可以通過繼承來靈活的擴展.

1、類裝飾器

class loging(object): def __init__(self,level='warn'):self.level = level def __call__(self,func):@functools.wraps(func)def _deco(*args, **kwargs): if self.level == 'warn':self.notify(func) return func(*args, **kwargs)return _deco def notify(self,func):# logit只打日志,不做別的print '%s is running' % func.__name__@loging(level='warn')#執行__call__方法def bar(a,b): print(’i am bar:%s’%(a+b))bar(1,3) 2、繼承擴展類裝飾器

class email_loging(Loging): ’’’ 一個loging的實現版本,可以在函數調用時發送email給管理員 ’’’ def __init__(self, email=’admin@myproject.com’, *args, **kwargs):self.email = emailsuper(email_loging, self).__init__(*args, **kwargs) def notify(self,func):# 發送一封email到self.emailprint '%s is running' % func.__name__print 'sending email to %s' %self.email@email_loging(level='warn')def bar(a,b): print(’i am bar:%s’%(a+b))bar(1,3)

以上就是python 裝飾器的使用與要點的詳細內容,更多關于python 裝飾器的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91精品国产经典在线观看| 一本综合精品| 国产免费播放一区二区| 亚洲精品观看| 日韩精品视频网站| 国产伦一区二区三区| 久久精品亚洲| 亚洲天堂一区二区| 国模 一区 二区 三区| 一区视频在线| 日韩高清不卡一区二区| 国产高清视频一区二区| 国产伦精品一区二区三区千人斩| 国产精品大片免费观看| caoporn视频在线| 欧美日韩国产综合网| 偷拍亚洲精品| 免费一级欧美片在线观看网站| 国产一区二区三区成人欧美日韩在线观看| av资源中文在线| 最新国产拍偷乱拍精品| 日韩中文字幕一区二区高清99| 国产精品亲子伦av一区二区三区| 成人国产精品| 亚洲欧美日韩综合国产aⅴ| 国产日韩欧美一区二区三区 | 亚洲一级淫片| 欧美久久香蕉| 日韩精品专区| 伊人久久大香伊蕉在人线观看热v| 91福利精品在线观看| 成人国产精品| 亚洲久草在线| 亚洲最新无码中文字幕久久| 欧美手机在线| 欧美一级久久| 午夜久久一区| 鲁大师精品99久久久| 伊人久久成人| 福利一区视频| 亚洲精品无播放器在线播放| 国产一区精品福利| 蜜臀精品一区二区三区在线观看 | 美女福利一区二区三区| 亚洲区第一页| 午夜精品成人av| 亚洲美女91| 999国产精品视频| 国产欧美在线| 先锋影音国产一区| 午夜精品成人av| 国产亚洲字幕| 亚洲综合丁香| 欧美一区久久久| 日韩不卡在线观看日韩不卡视频 | 免费观看亚洲| 欧美日韩a区| 日韩网站在线| 黄在线观看免费网站ktv| 人人精品人人爱| 麻豆视频在线看| 国产精品一区二区精品视频观看| 亚洲欧洲午夜| 日韩中文首页| 捆绑调教美女网站视频一区| 中文字幕一区二区av| 久久人人88| 精品国产a一区二区三区v免费| 亚洲精品乱码久久久久久蜜桃麻豆| 波多野结衣一区| 成人亚洲一区| 国产亚洲欧美日韩在线观看一区二区| 影音国产精品| 欧美成人基地 | 天海翼精品一区二区三区| 91精品在线观看国产| 久久99国产精品视频| 97久久亚洲| 亚洲精品乱码日韩| 99成人在线| 久久要要av| 在线一区av| 精品国产a一区二区三区v免费| 国产欧美日韩免费观看| 亚洲欧美日韩专区| 91久久中文| 黄色免费成人| 夜夜嗨网站十八久久| 在线日韩欧美| 免费成人网www| 亚洲午夜视频| 国产高清一区| 国产亚洲在线| 丝袜国产日韩另类美女| 亚洲深夜av| 国产精品免费看| 丝袜美腿成人在线| 日韩专区欧美专区| 亚洲在线网站| 亚洲综合欧美| 免费看精品久久片| 亚洲精品四区| 欧美亚洲一级| 粉嫩av一区二区三区四区五区 | 欧美日韩色图| 亚洲先锋成人| 一区视频在线| 在线视频亚洲欧美中文| 亚洲免费成人av在线| 97精品资源在线观看| 国产精区一区二区| 久久精品国产久精国产爱| 国产精品麻豆久久| 久久国产亚洲| 亚洲免费播放| 亚洲香蕉久久| 国产精品高清一区二区| 高清一区二区三区av| 亚洲高清激情| 久久国产高清| 亚洲精选91| 嫩呦国产一区二区三区av| 成人三级高清视频在线看| 激情欧美一区二区三区| 亚洲精品精选| 精品九九久久| 国产一区日韩欧美| 亚洲精品视频一二三区| 麻豆高清免费国产一区| 久久久久一区| 蜜臀av国产精品久久久久| 欧美天堂一区| 日韩国产激情| 免费观看在线综合| 国产精品色在线网站| 日本在线高清| 蜜桃一区二区三区在线| 国产欧美另类| 色爱av综合网| 日韩精品高清不卡| 国产精品二区不卡| 美国三级日本三级久久99| 麻豆一区二区三区| 激情综合网站| 国产亚洲字幕| 欧美日韩国产免费观看视频| 青青青国产精品| 99视频精品全国免费| 欧美视频久久| 香蕉久久99| 欧美午夜三级| 免费视频一区三区| 国产福利一区二区精品秒拍 | 久久免费精品| 美女精品在线观看| 久久电影tv| 青草久久视频| 欧美理论视频| 国产精品nxnn| 美女91精品| 成人亚洲一区二区| 噜噜噜久久亚洲精品国产品小说| 国产精品**亚洲精品| 中文日韩欧美| 亚洲伦乱视频| 国产精品mm| 亚洲区第一页| 成人av动漫在线观看| 国产一区二区三区黄网站 | 亚洲天堂一区二区| 国产毛片精品久久| 99在线|亚洲一区二区| 韩国久久久久久| 欧美影院视频| 视频一区二区三区入口| 91看片一区| 精品一区av| 日本不卡视频在线| 欧美日韩精品一本二本三本| 欧美aa一级| 丰满少妇一区| 国产精品黄色片| 婷婷综合成人| 性一交一乱一区二区洋洋av| 亚洲福利免费| 99久久激情| 特黄毛片在线观看| 国产精品sm| 国产美女久久| 日本国产一区| 亚洲3区在线| 亚洲一区二区日韩| 91精品高清| 欧美日韩色图| 国产91一区| 天堂网在线观看国产精品| 亚洲天堂免费电影| 国产精品毛片久久| 欧美国产美女| 福利一区二区免费视频|