十四、装饰器

装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作。

def f1(arg):

arg()

def func():

print (‘123‘)

f1(func) ======>f1接收的参数是一个函数

注:func返回的是内存地址,func()才是执行func这个函数

=====================================================

=====================================================

=====================================================

def f1():

print ‘f1‘ ========>连接数据库

def f2():

print ‘f2‘ ========>连接redis

def f3():

print ‘f3‘ ========>去硬盘拿数据

。。。。。。。

我这三个函数已经都写好了,并且已经都封闭了(即不能再往函数里面去做修改了),这个时候老板有个任务,希望对每个函数做验证,而函数又已经都是写好了的,已经封闭了,该怎么办?

思路是这样的,还是上面的例子(语法是错误的,只是解释原理):

def f1(arg):

print (‘验证’)

arg()

def func():

print (‘123‘)

#1.将被调用函数封装到另外一个函数里边

func = f1(func)

#2.将原函数重新赋值

func()

我们看见这样就解决了问题(只是原理,语法并不是这样)。

=========================================================

=========================================================

=========================================================

具体做法是这样的:

def auth(func): =======>我在上边新加了一个具有验证功能的函数,下面执行这个函数,就会发现将f1作为参数传给func函数,以后 就等价于func = f1 ======>func() <======>f1()

def inner(): ==========>函数里又嵌套一个函数

print (‘before‘)

func() =========f1 =====>原函数

return inner

def f1():

print ‘f1‘ ========>连接数据库

ret1 = auth(f1) = def inner():

print (‘before‘)

f1()#原来f1

f1 = ret1

def f2():

print ‘f2‘ ========>连接redis

ret2 = auth(f2) = def inner():

print (‘before‘)

f2()#原来f2

f2 = ret2

def f3():

print ‘f3‘ ========>去硬盘拿数据

ret3 = auth(f3) = def inner():

print (‘before‘)

f3()#原来f3

f3 = ret3

。。。。。。。

result = auth(f1) = def inner():

print (‘before‘)

func()

result() #它现在就等于执行inner()这个函数了,执行inner这个函数就是执行了f1这个原函数了

上面的写法是为了理解装饰器的原理和工作过程,不过自己都看不懂了,

=================================================================================================

=================================================================================================

=================================================================================================

完整写好的是这样的:

def auth(func):

def inner():

print (‘before,验证‘) ====>在执行函数之前增加一个验证功能。

func()

print (‘after,写日志‘) ====>在执行函数之后增加一个写日志功能。

return inner

@auth

def f1():

print ‘f1‘ ========>连接数据库

@auth

def f2():

print ‘f2‘ ========>连接redis

@auth

def f3():

print ‘f3‘ ========>去硬盘拿数据

。。。。。。。

总结:

第一步:先写一个嵌套函数,将需要增加的功能写在内层函数里

第二步:在每个需要新增功能的函数上面加上装饰器即@auth

====================================================================================================

====================================================================================================

====================================================================================================

装饰器去装饰含参数的函数:

def auth(func): ====>装饰没有参数的函数

def inner():

print (‘before,验证‘) ====>在执行函数之前增加一个验证功能。

func()

print (‘after,写日志‘) ====>在执行函数之前增加一个写日志功能。

return inner

def auth_arg(func): ====>重新定义一个装饰器装饰有参数的函数

def inner(arg):

print (‘before,验证‘) ====>在执行函数之前增加一个验证功能。

func(arg)

print (‘after,写日志‘) ====>在执行函数之前增加一个写日志功能。

return inner

@auth

def f1():

print ‘f1‘ ========>连接mysql

@auth_arg

def f4(arg): ========>连接oracle(带参数)

print ‘f4,arg‘

缺点:总结以上的方案我们发现,我没带参数写个装饰器,我带1个需要写个装饰器,带2个需要写个装饰器。。。。。。。

完美解决方案就是利用万能动态参数,如下,这样不管你传不传参数,不管你传几个参数就都没有问题了。

------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------

def auth(func):

def inner(*args,**kwargs):

print (‘before,验证‘)

func(*args,**kwargs)

print (‘after,写日志‘)

return inner

@auth

def f1():

print ‘f1‘ ========>连接mysql

@auth

def f4(arg): ========>连接oracle(带1个参数)

print ‘f4,arg‘

@auth

def f5(arg1,arg2,arg3,arg4): ========>连接redis(带4个参数)

print ‘f5,arg1,arg2,arg3,arg4‘

==================================================================================================

==================================================================================================

==================================================================================================

装饰器去装饰含返回值的函数:

def auth(func):

def inner(*args,**kwargs):

print (‘before,验证‘)

temp = func(*args,**kwargs)

print (‘after,写日志‘)

return temp

return inner

@auth

def fetch_host_list(arg): =====>获取主机列表

host_list = [‘h1‘,‘h2‘,‘h3‘]

return host_list

=====================================================================================================

=====================================================================================================

=====================================================================================================

装饰器实现登录验证原理(这个是装饰器应用最多的场景):

def login():

name = ‘rooney‘

if name == ‘rooney‘:

return True

else:

return False

def auth(func):

def inner(*args,**kwargs):

is_login = login()

if not is_login:

return "你输入的用户名不正确"

temp = func(*args,**kwargs)

print (‘after,写日志‘)

return temp

return inner

@auth

def fetch_host_list(arg): =====>获取主机列表

host_list = [‘h1‘,‘h2‘,‘h3‘]

return host_list

=======================================================================================================

=======================================================================================================

=======================================================================================================

装饰器实现token验证:

def login(key):

local = ‘fdsareqwrwq12345d2srwq‘

if local == key:

return True

else:

return False

def auth(func):

def inner(*args,**kwargs):

#fetch_server_list(‘test‘,token=key) ====>业务线传了两个参数进来

key = kwargs.pop(‘token‘)

is_login = login(key)

if not is_login:

return "你输入的用户名不正确"

temp = func(*args,**kwargs)

print (‘after,写日志‘)

return temp

return inner

@auth

def fetch_host_list(arg): =====>获取主机列表

host_list = [‘h1‘,‘h2‘,‘h3‘]

return host_list

==========================================================================================================

==========================================================================================================

==========================================================================================================

装饰器之多装饰器(盒子模型):

def w1(func):

def inner(*args,**kwargs):

print (‘w1,before‘)

func(*args,**kwargs)

print (‘w1,after‘)

return inner

def w2(func):

def inner(*args,**kwargs):

print (‘w2,before‘)

func(*args,**kwargs)

print (‘w2,after‘)

return inner

@w2

@w1

def foo():

print (‘foo‘)

foo()

返回结果竟然是这样:

w2,before

w1,before

foo

w1,after

w2,after

套盒子,foo是一个盒子,上面加个w1装饰器就相当于外面又套了一层盒子,再加一个装饰器就相当于再套了个盒子,那么你打开的时候就是从外往里打开拿出来。

=====================================================================================

=====================================================================================

=====================================================================================

装饰器之装饰器加参数:

#!/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‘

比如说:下面两个装饰器,一个带参数,一个不带参数

@w1

1.执行w1函数

2.将w1函数的返回值赋值给被装饰器装饰的函数的函数名

@w2

1.执行w2函数,得到返回值,ret

2.创建装饰器,@ + ret结合;@ret

3.。。。。。。。

1.执行ret函数

2.将ret函数的返回值赋值给被装饰器装饰的函数的函数名

原文地址:https://www.cnblogs.com/steven9898/p/11329419.html

时间: 2024-10-30 09:37:00

十四、装饰器的相关文章

十四 —— 装饰器

设置类属性 1.@property装饰器,是python内置的装饰器,可以把类的方法伪装成属性调用的方式, 2.python内置的builtins模块中的property()函数 property(get_age, set_age, del_age, "年龄"):前面三个参数是方法名.调用时自动执行的方法,最后一个参数是个字符串,他用来做描述 原文地址:https://www.cnblogs.com/KeenaCherry/p/12110212.html

(十)装饰器模式详解(与IO不解的情缘)

LZ到目前已经写了九个设计模式,回过去看看,貌似写的有点凌乱,LZ后面会尽量改进. 那么本章LZ和各位读友讨论一个与JAVA中IO有着不解情缘的设计模式,装饰器模式. 定义:装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.                  这一个解释,引自百度百科,我们注意其中的几点. 1,不改变原类文件.                  2,不使用继承.                  3,动

十六.装饰器

装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print '2013-12-25' ... >>> f = now >>> f() 2013-12-25 函数对象有一个__name__属性,可以拿到函数的名字: >>> now.__name__ 'now' >>> f.__name__ 'now' 现在,假设我们要增强now()函数的

Python学习(十)—— 装饰器和函数闭包

装饰器 装饰器:本质就是函数,功能是为其他函数添加附加功能 原则: 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 统计程序运行的时间(不使用装饰器): 这种方法修改了源代码,不能用于已经上线的程序 1 import time 2 def calc(l): 3 res = 0 4 start_time = time.time() 5 for i in l: 6 res += i 7 time.sleep(0.01) 8 stop_time = time.time() 9 print

Struts2(十四)拦截器实现权限管理

一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截Action请求 在访问的Action执行之前和执行之后执行代码实现某项功能 Struts2: 大部分功能是在拦截器中实现的如:接收输入的参数,数据验证,文件上传,国际化等 应用程序: 需要在Action执行的前后执行特定功能 Action执行时间统计,Action访问权限管理 Action添加功能

15 装饰器

三十四.装饰器 1.开闭原则: 对功能的扩展开放,对代码的修改是封闭的(不可修改的)    目的:在目标函数前或后插入一段新的代码,不改变源代码 2.装饰器的通用语法 3.多个装饰器修饰同一个函数 4.带参数的修饰器 语法格式: 实例: 原文地址:https://www.cnblogs.com/lw1095950124/p/10197811.html

Python(十) 函数式编程: 匿名函数、高阶函数、装饰器

一.lambda表达式 lambda parameter_list: expression # 匿名函数 def add(x,y): return x+y print(add(1,2)) f = lambda x,y: x+y print(f(1,2)) 二.三元表达式 # x >y ? x :y # 条件为真时返回的结果 if 条件判断 else 条件为假时的返回结果 x= 2 y=1 r = x if x > y else y print(r) # 2 三.map 四.map与lambda

兄弟连学Python 装饰器和抽象类

#装饰器:对类或者函数进行功能的扩展 ''' #第一步:基本函数 def la(): print('脚踏黄河两岸,手拿机密文件,前面机枪扫射,后面炮火连天') #调用函数 la() la() #第二步:扩展函数功能(不能修改原函数) #用于扩展基本函数的函数 def kuozhan(func): #扩展功能1 print('la前参拜祈求') #调用基本函数 func() #扩展功能2 print('la后还愿感谢') #基本函数 def la(): print('脚踏黄河两岸,手拿机密文件,前

002_第三部分_[函数 / 高阶函数 / 装饰器]

一.高阶函数: 顺序排序 enumerate([1,2 ,3 , 4, 5]) for idx, item in enumerate([1, 2, 3, 4]):     print(idex)     print(item) def sort(*args):     ret = []     for item in args:         for i, v in enumerate(ret):             if item > v:                 ret.ins

Python学习之路7?装饰器

一:命名空间与作用域 1.1命名空间 局部命名空间: def foo(): x=1 def func(): pass 全局命名空间: import time class ClassName:pass def foo():pass 内键命名空间: sum,max,min 等 python加载三个命名空间的顺序: 1.内键命名空间 2.全局命名空间:文件级别的或叫做模块级别的 3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉 1.2作用域 全局作用域: 1 同时x=1为全局变量