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 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...
随机推荐
- 2016word多级列表 一级标题居中后偏左
一.如下图所示,定义好多级列表之后设置标题,但是发现标题居中后偏左. 二.选择多级列表,设置居左对齐
- Java框架spring 学习笔记(十二):aop实例操作
使用aop需要在网上下载两个jar包: aopalliance.jar aspectjweaver.jar 为idea添加jar包,快捷键ctrl+shift+alt+s,打开添加jar包的对话框,将 ...
- 解题(GoUpstairs -- 上楼梯)
题目描述 有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶.2阶.3阶.请实现一个方法,计算小孩有多少种上楼的方式.为了防止溢出,请将结果Mod 1000000007 给定一个正整数int n, ...
- Oracle获取一周前,一个月前,一年前, 本周,本月,当年的日期
1.获取当前时间一周前的日期 ' day from dual 类似的 --当前时间减去7分钟的时间 ' MINUTE from dual --当前时间减去7小时的时间 ' hour from dual ...
- java将一个List赋值给另一个List
声明和实例化: 声明:ArrayList a, 仅仅只是声明了一个list变量,其未来作用相当于C++中的引用变量,亦或者相当于一个对象块的索引,但并未为其分配具体的完整的对象所需要的内存空间,其所分 ...
- java实现将包含多个<REC>的文件拆成若干只包含一个<REC>的文件
遍历文件夹里的文件,将包含多个<REC>的文件拆成若干只包含一个<REC>的文件 package com.prepub; import java.io.BufferedRead ...
- ThinkPHP学习笔记
1.什么是框架? 特征一:是一对代码的集合: 特征二:一个半成品的应用: 特征三:包含了一些优秀的设计模式: 定义:框架是一堆包含了常量.方法和类等代码的集合,它是一个半成品的应用,只包含了一些项目开 ...
- mysql数据库优化之 如何选择合适的列建立索引
1. 在where 从句,group by 从句,order by 从句,on 从句中出现的列: 2. 索引字段越小越好: 3. 离散度大的列放到联合索引的前面:比如: select * from p ...
- 【LeetCode刷题系列 - 002题】Add Two Numbers
题目: You are given two non-empty linked lists representing two non-negative integers. The digits are ...
- python字符串之format格式化函数
学习中~ 觉得应该系统地学习一下python,今天学习了字符串,以下是自己的笔记. 首先说一下format函数,用{}和:代替了%,比如: >>>“{} {} {}”.format( ...