装饰器

某公司的基础业务平台如下:

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之路(九)-函数装饰器的更多相关文章

  1. python学习日记(函数--装饰器)

    楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...

  2. python语言中的函数装饰器

    装饰器 什么是装饰器? 装饰:给已有的对象(函数)添加新的功能 器:工具              在python中指具备某些功能的函数 装饰器:装饰器就是一个给其他函数增加功能的函数 一种设计原则: ...

  3. Python: 无参数的函数装饰器

    写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数.但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函 ...

  4. Python带参数的函数装饰器

    # -*- coding: utf-8 -*- # author:baoshan # 带参数的函数装饰器 def say_hello(country): def wrapper(func): def ...

  5. Python学习第四十一天函数装饰器传参数的用法

    在不改变函数的结构的基础,我们给函数加新的功能,用是函数装饰器,如果要给函数传递参数,那么应该怎么做呢 @timerdef test2(name,age): time.sleep(3) print(' ...

  6. 流畅的python第七章函数装饰器和闭包学习记录

    本章讨论的话题 python如何计算装饰器句法 python如何判断变量是不是局部的(通过函数内部是否给变量赋值过来判断是否是局部变量) 闭包存在的原因和工作原理(闭包是一种函数,它会保留定义函数时存 ...

  7. 【python之路24】装饰器

    1.装饰器的应用场景 通常IT公司的程序开发是分工的,例如某公司某个部门负责底层函数的开发,另一个部门利用其函数实现高级功能,那么如果负责底层开发的函数需要改动,一般来说不会直接在函数上进行修改,通常 ...

  8. Python学习笔记九:装饰器,生成器,迭代器

    装饰器 本质是函数,装饰其他函数,为其他函数添加附加功能 原则: 1不修改原函数的源代码 2不修改原函数的调用方式 知识储备: 1函数即变量 使用门牌号的例子说明函数,调用方式与变量一致 2高阶函数 ...

  9. Python小白学习之函数装饰器

    装饰器 2018-10-25 13:49:37 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...

随机推荐

  1. C语言典型编程2

    关于C的一些小而精的编程,适合希望提升编程能力的初学者学习:关键编程也就几句,但思维可以迁移到其他编程语言.同一问题,算法多种. //任意整数的任意次方取后3位(算数取位)#include<st ...

  2. SecureCRT连接开发板 串口传输、tftp传输

    1.串口传输 使用命令:rx  r是service, x是X-model模式 ①.rx 文件名 再按Enter键 ②.将需要传到板子上的文件 拖到SecureCRT里面,选择发送X-model选项 注 ...

  3. pandas,pd.ExcelWriter保存结果到已存在的excel文件中

    背景:pandas支持将DataFrame数据直接保存到excel中   保存的case如下: import pandas as pd with pd.ExcelWriter('a.xls') as ...

  4. Dockerfile的常见命令

    FROM 格式: FROM  <image> 或者  FROM <image>:<tag> FROM指令的功能是为后面的指令提供基础镜像,所以该指令一定是Docke ...

  5. ROC AUC

    1.什么是性能度量? 我们都知道机器学习要建模,但是对于模型性能的好坏(即模型的泛化能力),我们并不知道是怎样的,很可能这个模型就是一个差的模型,泛化能力弱,对测试集不能很好的预测或分类.那么如何知道 ...

  6. UIButton设置UIControlContentHorizontalAlignment调整文字对齐方式

    UIButton 继承自UIControl,所以可以对UIControlContentHorizontalAlignment进行设置 btn.setImage(UIImage.init(named: ...

  7. 分支&循环

    分支 单分支 if 条件: 满足条件后要执行的代码 双分支 if 条件: 满足条件执行代码 else: if条件不满足就走这段 多分支: if 条件: 满足条件执行代码 elif 条件: 上面的条件不 ...

  8. rabbitmq 启动报错 Failed to get nic info

    这个报错 基本搜索不到什么有效信息 解决办法: hostnamectl set-hostname xxx.local # 先把rabbitmq进程杀掉$ ps -ef | grep rabbitmq ...

  9. wpf 寻找TreeView的子元素,并对其进行操作

    //itemsControl 开始为指定的TreeView控件  item为TreeView子元素 private void PareItems(ItemsControl itemsControl, ...

  10. python3下获取全局坐标

    前段时间自己想用python写一个关于截屏翻译的小功能,所以首先需要获取鼠标的坐标动作有按下.拖拽.释放.查找了很多资料无非是pyhook或者用其他语言重写.但是自己用的是python3.65,第三方 ...