电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

python 裝飾器的使用與要點

瀏覽:7日期: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 編程
相關文章:
主站蜘蛛池模板: 分光色差仪,测色仪,反透射灯箱,爱色丽分光光度仪,美能达色差仪维修_苏州欣美和仪器有限公司 | 西安中国国际旅行社(西安国旅) | 船用烟火信号弹-CCS防汛救生圈-船用救生抛绳器(海威救生设备) | 北京开业庆典策划-年会活动策划公司-舞龙舞狮团大鼓表演-北京盛乾龙狮鼓乐礼仪庆典策划公司 | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) | 液压扳手-高品质液压扳手供应商 - 液压扳手, 液压扳手供应商, 德国进口液压拉马 | 开云(中国)Kaiyun·官方网站 - 登录入口 | 没斑啦-专业的祛斑美白嫩肤知识网站-去斑经验分享 | 飞扬动力官网-广告公司管理软件,广告公司管理系统,喷绘写真条幅制作管理软件,广告公司ERP系统 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 黄石东方妇产医院_黄石妇科医院哪家好_黄石无痛人流医院 | 浙江宝泉阀门有限公司| 广州中央空调回收,二手中央空调回收,旧空调回收,制冷设备回收,冷气机组回收公司-广州益夫制冷设备回收公司 | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 山东螺杆空压机,烟台空压机,烟台开山空压机-烟台开山机电设备有限公司 | 河南橡胶接头厂家,河南波纹补偿器厂家,河南可曲挠橡胶软连接,河南套筒补偿器厂家-河南正大阀门 | 机械立体车库租赁_立体停车设备出租_智能停车场厂家_春华起重 | 报警器_家用防盗报警器_烟雾报警器_燃气报警器_防盗报警系统厂家-深圳市刻锐智能科技有限公司 | 【中联邦】增稠剂_增稠粉_水性增稠剂_涂料增稠剂_工业增稠剂生产厂家 | 临时厕所租赁_玻璃钢厕所租赁_蹲式|坐式厕所出租-北京慧海通 | 100国际学校招生 - 专业国际学校择校升学规划 | 氧化锆陶瓷_氧化锆陶瓷加工_氧化锆陶瓷生产厂家-康柏工业陶瓷有限公司 | 考勤系统_人事考勤管理系统_本地部署BS考勤系统_考勤软件_天时考勤管理专家 | 塑料薄膜_PP薄膜_聚乙烯薄膜-常州市鑫美新材料包装厂 | 防火门-专业生产甲级不锈钢钢质防火门厂家资质齐全-广东恒磊安防设备有限公司 | 深圳南财多媒体有限公司介绍| RV减速机-蜗轮蜗杆减速机-洗车机减速机-减速机厂家-艾思捷 | 石栏杆_青石栏杆_汉白玉栏杆_花岗岩栏杆 - 【石雕之乡】点石石雕石材厂 | 清水-铝合金-建筑模板厂家-木模板价格-铝模板生产「五棵松」品牌 | 开锐教育-学历提升-职称评定-职业资格培训-积分入户 | 订做不锈钢_不锈钢定做加工厂_不锈钢非标定制-重庆侨峰金属加工厂 | 包塑丝_高铁绑丝_地暖绑丝_涂塑丝_塑料皮铁丝_河北创筹金属丝网制品有限公司 | 绿萝净除甲醛|深圳除甲醛公司|测甲醛怎么收费|培训机构|电影院|办公室|车内|室内除甲醛案例|原理|方法|价格立马咨询 | 不锈钢闸阀_球阀_蝶阀_止回阀_调节阀_截止阀-可拉伐阀门(上海)有限公司 | 北京成考网-北京成人高考网| 板框压滤机-隔膜压滤机-厢式压滤机生产厂家-禹州市君工机械设备有限公司 | 光照全温振荡器(智能型)-恒隆仪器| 色油机-色母机-失重|称重式混料机-称重机-米重机-拌料机-[东莞同锐机械]精密计量科技制造商 | 无痕胶_可移胶_无痕双面胶带_可移无痕胶厂家-东莞凯峰 | 智能气瓶柜(大型气瓶储存柜)百科| 洁净棚-洁净工作棚-无菌室-净化工程公司_北京卫护科技有限公司 |