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 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...
随机推荐
- Java8自定义函数式编程接口和便捷的引用类的构造器及方法
什么是函数编程接口? 约束:抽象方法有且只有一个,即不能有多个抽象方法,在接口中覆写Object类中的public方法(如equal),不算是函数式接口的方法. 被@FunctionalInterfa ...
- C# 多线程传递参数或多个参数
using System;using System.IO;using System.Text;using System.Threading; namespace ConsoleApp7{ class ...
- SVN添加用户
1. 找到svn安装路径 /svn/repositories/ (如果不知道,可以搜索 :find / -name svn或者是ps -ef | grep svn) 2.进入该目录的conf,其中包 ...
- springboot+maven多模块工程dependency not found
参见:https://blog.csdn.net/m0_37943753/article/details/81031319. 重点是<dependencyManagement>标签的作用, ...
- ThinkPHP学习笔记
1.什么是框架? 特征一:是一对代码的集合: 特征二:一个半成品的应用: 特征三:包含了一些优秀的设计模式: 定义:框架是一堆包含了常量.方法和类等代码的集合,它是一个半成品的应用,只包含了一些项目开 ...
- Jmeter之集合点(Synchronizing timer 同步定时器)
1.集合点介绍 LR中集合点可以设置多个虚拟用户等待到一个点,同时触发一个事务,以达到模拟真实环境下多个用户同时操作,实现性能测试的最终目的.jmeter中使用Synchronizing Timer实 ...
- 48-设置tomcat虚拟路径的两种方法(Eclipse、tomcat、IDEA)
设置tomcat虚拟路径的两种方法(Eclipse.tomcat.IDEA) 三种方式设置虚拟服务器路径如果我们要实现一个上传文件的功能,但是又想要上传的文件不会随着自己web服务器的重启而不能访问了 ...
- NoteBook学习(二)-------- Zeppelin简介与安装
Zeppelin官网地址: http://zeppelin.apache.org/ Github地址: https://github.com/apache/zeppelin (参照官网) 1.什么是z ...
- ajax执行成功不进入success方法
当dataType的值为json时,传入的值和返回的值符合json格式的时候,执行成功才会进入success方法,否则进入error方法.
- chip8模拟器的python3实现-2-指令介绍
CHIP指令表 CHIP-8有35个指令,都为两字节长,以大端方式存储.指令表的指令格式规定如下: NNN:地址 NN:8位常量 N:4位常量 V:寄存器 X和Y:4位,标识寄存器 PC:程序计数器 ...