python之路(九)-函数装饰器
装饰器
某公司的基础业务平台如下:
def f1():
print('这是f1业务平台')
def f2():
print('这是f2业务平台') def f3():
print('这是f3业务平台')
def f4():
print('这是f4业务平台')
def f5():
print('这是f5业务平台')
各业务部门是这样调用的:
#f1业务部门调用
f1() #f2业务部门调用
f2() #f1业务部门调用
f3() #f4业务部门调用
f4() #f5业务部门调用
f5()
随着公司的规模扩大,每个业务部门的研发越来越多,为了规范管理,此时需要各业务部门的研发在调用以上方法之前先登陆,认证成功后方可调用,有如下方案:
1. 让业务部门自己写登陆程序。
2. 基础平台写好认证程序,告诉业务部门研发在调用方法前先调用验证的方法。
3. 基础平台写好认证程序,并在每个方法内加入该验证程序。
4. 基础平台写好认证程序,然后再不改动原方法并且不改变业务部门调用原方法方式实现认证。
分析下以上方法,方法1肯定不合适,业务部门自己验证自己显然不符合要求。方法2每个业务部门都改变了调用方法,也不合适。方法3虽然没有改变业务部门调用方法但是在每个方法内加入同样的多行代码太复杂。方法4非常好,此时就需要用到函数装饰器具。
示例:
def wrapper(func):
def inner():
print('验证成功')
func()
return inner @wrapper
def f1():
print('这是f1业务平台') @wrapper
def f2():
print('这是f2业务平台') @wrapper
def f3():
print('这是f3业务平台') @wrapper
def f4():
print('这是f4业务平台') @wrapper
def f5():
print('这是f5业务平台') #f1业务部门调用
f1() #f2业务部门调用
f2() #f1业务部门调用
f3() #f4业务部门调用
f4() #f5业务部门调用
f5()
以上装饰器中,
@wrapper表示要对下面的函数进行装饰,此时要做的操作是:首先执行wrapper函数,然后将要装饰的函数名作为参数传给wrapper函数,wrapper函数的内容是定义了一个inner函数(注意只是定义了inner函数,并未执行),inner函数内先执行登陆功能函数,然后在执行被装饰的函数,所以wrapper函数相当于重新包装了一下被装饰的函数,比如f1函数,在包装f1函数的时候先执行了验证的方法,然后再执行f1函数。此时如果业务部门执行f1函数,那么他执行的是被包装后的函数及inner函数。此为装饰器。 问题:被装饰的函数如果有参数呢?
示例1:一个参数
def wrapper(func):
def inner(args):
print('login successfull!')
func(args)
return inner @wrapper
def f1(args):
print('your name is %s' %args) f1('Tomcat')
#输出结果:
login successfull!
your name is Tomcat
#我们说了 inner函数就是装饰器重新包装的被装饰的函数,所以inner函数的参数就是原函数f1的参数
示例2:两个参数
def wrapper(func):
def inner(args1,args2):
print('login successfull!')
func(args1,args2)
return inner @wrapper
def f1(args1,args2):
print('your name is %s and your age is %s' %(args1,args2)) f1('Tomcat','') #输出结果:
login successfull!
your name is Tomcat and your age is 23
示例3:三个参数
def wrapper(func):
def inner(*args,**kwargs):
print('login successfull!')
func(*args,**kwargs)
return inner @wrapper
def f1(args1,args2,args3):
print('your name is %s and your age is %s,%s' %(args1,args2,args3)) f1('Tomcat','','boy') #输出结果:
login successfull!
your name is Tomcat and your age is 23,boy
更叼的装饰器(装饰器具中带参数):
#!/usr/bin/env python
#coding:utf-8 def Before(request,kargs):
print 'before' def After(request,kargs):
print 'after' def Filter(before_func,after_func):
def outer(main_func):
def wrapper(request,kargs): before_result = before_func(request,kargs)
if(before_result != None):
return before_result; main_result = main_func(request,kargs)
if(main_result != None):
return main_result; after_result = after_func(request,kargs)
if(after_result != None):
return after_result; return wrapper
return outer @Filter(Before, After)
def Index(request,kargs):
print 'index'
python之路(九)-函数装饰器的更多相关文章
- python学习日记(函数--装饰器)
楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...
- python语言中的函数装饰器
装饰器 什么是装饰器? 装饰:给已有的对象(函数)添加新的功能 器:工具 在python中指具备某些功能的函数 装饰器:装饰器就是一个给其他函数增加功能的函数 一种设计原则: ...
- Python: 无参数的函数装饰器
写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数.但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函 ...
- Python带参数的函数装饰器
# -*- coding: utf-8 -*- # author:baoshan # 带参数的函数装饰器 def say_hello(country): def wrapper(func): def ...
- Python学习第四十一天函数装饰器传参数的用法
在不改变函数的结构的基础,我们给函数加新的功能,用是函数装饰器,如果要给函数传递参数,那么应该怎么做呢 @timerdef test2(name,age): time.sleep(3) print(' ...
- 流畅的python第七章函数装饰器和闭包学习记录
本章讨论的话题 python如何计算装饰器句法 python如何判断变量是不是局部的(通过函数内部是否给变量赋值过来判断是否是局部变量) 闭包存在的原因和工作原理(闭包是一种函数,它会保留定义函数时存 ...
- 【python之路24】装饰器
1.装饰器的应用场景 通常IT公司的程序开发是分工的,例如某公司某个部门负责底层函数的开发,另一个部门利用其函数实现高级功能,那么如果负责底层开发的函数需要改动,一般来说不会直接在函数上进行修改,通常 ...
- Python学习笔记九:装饰器,生成器,迭代器
装饰器 本质是函数,装饰其他函数,为其他函数添加附加功能 原则: 1不修改原函数的源代码 2不修改原函数的调用方式 知识储备: 1函数即变量 使用门牌号的例子说明函数,调用方式与变量一致 2高阶函数 ...
- Python小白学习之函数装饰器
装饰器 2018-10-25 13:49:37 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...
随机推荐
- Arthas的基础学习
下载与安装 wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 启动 查看启动的帮助信息: ...
- 使用WebClient调用第三方接口
需要调用一个第三方接口,传参返回数据 本来是很简单的一个需求,搞了一天没整好 首先在POSTMAN中测试没有问题,但是使用jquery ajax在前台就会涉及到跨域 虽然设置了 无论怎么写都会报错 C ...
- springboot指定端口的三种方式
第一配置文件中添加server.port=9090 第二在命令行中指定启动端口,比如传入参数一server. port=9000 java -jar bootsample. jar -- se ...
- ucos中信号量 事件标志 消息队列都怎么用
信号量 事件标志和消息队列分别应用于什么场景(反正我学的时候有点闹不清,现在总结一下): 信号量和事件标志用于任务同步.详细来说,这个功能可以替代以前裸机中你打一个标记的功能,比如使用了一个定时器,5 ...
- 记第一次XSS实战
前两天偶然挖到一个XSS,在我低谷期的时候给了我些动力,遂写下这篇博客记录 随手在一个搜索框中测试,发现有反应 观察一下标签,需要">把前面的闭合,然后<a 把后面的标签闭合 结 ...
- 用eclipse创建动态web项目手动生成web.xml方法
建一个web项目,后来在用到web.xml文件时,才发现项目创建时没有自动创建web.xml文件. 在创建的项目上单击右键,然后单击java EE Tools下的用红线圈住的地方,然后查看你的WEB- ...
- Leetcode1000 合并石头的最低成本 区间DP
有 N 堆石头排成一排,第 i 堆中有 stones[i] 块石头. 每次移动(move)需要将连续的 K 堆石头合并为一堆,而这个移动的成本为这 K 堆石头的总数. 找出把所有石头合并成一堆的最低成 ...
- 网络通信实验(2)TCP/IP LWIP 简介
TCP/IP 简介 TCP/IP 中文名为传输控制协议/因特网互联协议,又名网络通讯协议,是 Internet 最基本的协议. Internet 国际互联网络的基础,由网络层的 IP 协议和传输层的 ...
- JS 中常见数组API使用方法(join、concat、slice、splice、reverce)
刚接触前端不久,个人觉得学习程序还是需要经常总结的.下面是我的一些知识的归纳总结,如果哪里说得不对的还请各位大神指点! 1.to str (1)String(arr)将数组中的每个元素转为字符串并用逗 ...
- 10.spring-boot基于角色的权限管理页面实现
10.spring-boot基于角色的权限管理页面实现