python装饰器系列(五)

带参数的装饰器的应用:

比如有一个函数,只有在对有许可权限的用户开放,执行此函数的用户没有在认证列表里的,就不会执行这个函数。这个该如何实现呢?如下:

 1 def check(allow_users):
 2     def inner_check(fn):
 3         def wrap(username,*args,**kwargs):
 4             ‘‘‘This is wrap‘‘‘
 5             if username in allow_users:
 6                 return fn(username,*args,**kwargs)
 7             return "You are illegal users"
 8         return wrap
 9     return inner_check
10
11
12 @check([‘zhaochj‘,‘zcj‘])
13 def private(username):
14     ‘‘‘The authentication‘‘‘
15     return "You are legitimate users"
1 private(‘zhaochj‘)
2 ‘You are legitimate users‘
1 private(‘tom‘)
2 ‘You are illegal users‘

这样就可以对调用函数进行身份验证

python中一个函数有一些属性是函数本身具有的,比如__name__属性是查看函数名称,如果一个函数被装饰器装饰过后,这个函数的这些属性会发生怎样的变化呢?

以上边的check装饰器和private函数为例子,如下:

1 private.__name__
2 ‘wrap‘

private函数的名称是wrap了,这是怎么回事?上边已经说过,这里的private函数被装饰器装饰后它已不再是原来的private函数,private这个函数名称会被指向到wrap这个函数对象,那当然用上边的private.__name__查看函数的属性就会是wrap函数的属性。

那怎样来修正呢?可以这样做,如下:

 1 def check_1(allow_users):
 2     def inner_check(fn):
 3         def wrap(username,*args,**kwargs):
 4             ‘‘‘This is wrap‘‘‘
 5             if username in allow_users:
 6                 return fn(username,*args,**kwargs)
 7             return "You are illegal users"
 8         wrap.__name__ = fn.__name__
10         return wrap
11     return inner_check
12
13 @check_1([‘zhaochj‘,‘zcj‘])
14 def private_1(username):
15     ‘‘‘The authentication‘‘‘
16     return "You are legitimate users"
1 private_1.__name__
2 ‘private_1‘

通过在装饰器把__name__重新赋值后就能更正这个问题,但对一个函数来说像__name__这样类似的属性有许多,如果都是这样手工来修正显然是不现实的,所以python提供了一个wraps装饰器来自动修正这个问题,wrapsfunctools这个包中,所以可以这样来修正这个问题,如下:

 1 import functools
 2
 3 def check_1(allow_users):
 4     def inner_check(fn):
 5         @functools.wraps(fn)
 6         def wrap(username,*args,**kwargs):
 7             ‘‘‘This is wrap‘‘‘
 8             if username in allow_users:
 9                 return fn(username,*args,**kwargs)
10             return "You are illegal users"
11         return wrap
12     return inner_check
13
14 @check_1([‘zhaochj‘,‘zcj‘])
15 def private_1(username):
16     ‘‘‘The authentication‘‘‘
17     return "You are legitimate users"
1 private_1.__name__
2 ‘private_1‘

@functools.wraps(fn)这个装饰器相当于执行了wrap.__name__ = fn.__name__这样的操作

原文地址:https://www.cnblogs.com/tianshug/p/10921944.html

时间: 2024-10-01 00:29:06

python装饰器系列(五)的相关文章

python装饰器系列(二)

对python装饰器系列(一)的deco函数进行修改: 1 def deco(fn): 2 def wrap(): 3 print('ha ha ha') 4 print('call {0} funtion'.format(fn.__name__)) 5 fn() 6 return wrap 1 @deco 2 def myfun(): 3 print('call myfun') 1 myfun() 2 3 ha ha ha 4 call myfun funtion 5 call myfun m

python装饰器系列(三)

装饰器的应用实例 1 import time 2 def timeit(fn): 3 start = time.time() 4 fn() 5 print(time.time() - start) 6 7 def sleep(): 8 time.sleep(3) 上边代码定义了两个函数,timeit函数能够模拟计算出在执行fn函数所花费的时间 1 timeit(sleep) 2 3.003638505935669 这样来计算一个函数的执行时间是有缺陷的,sleep函数必须是一个接收参数的函数,那

由浅入深,走进Python装饰器-----第五篇:进阶--类装饰类

**类装饰器** @类 类 4.1 用类装饰器来扩展原类( 增加属性和方法 ) # 用类装饰器来扩展原函数, 通过对象函数化触发__call__方法,进行返回 class KuoZhan(): def __call__(self,cls): return self.newfunc(cls) def good(self): print("新增的方法!") def newfunc(self,cls): def in_newfunc(): cls.addpty = "新增的属性&q

python装饰器系列(四)

带参数的装饰器 先来看一个不带参数的装饰器 1 import time 2 3 def timeit(fn): 4 def wrap(*args,**kwargs): 5 start = time.time() 6 ret = fn(*args,**kwargs) 7 print(time.time() - start) 8 return ret 9 return wrap 10 11 12 @timeit 13 def sleep(x): 14 time.sleep(x) 1 sleep(3)

Python装饰器由浅入深

装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们以装饰函数为例子介绍其用法.要理解在Python中装饰器的原理,需要一步一步来.本文尽量描述得浅显易懂,从最基础的内容讲起. (注:以下使用Python3.5.1环境) 一.Python的函数相关基础 第一,必须强调的是python是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行它的,只

【转】九步学习python装饰器

本篇日志来自:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 纯转,只字未改.只是为了学习一下装饰器.其实现在也是没有太看明白,对于装饰器我就是用的时候找例子,能蒙对,但是用过之后一段时间就忘了.还是用的少.有空应该好好看一看的,包括闭包.对于各种现代编程语言来说闭包都是很重要的.在这里先谢过原作者,如有侵权请告知. =-=-=-=-=-=-=-=-=-=-一条不怎么华丽的分隔线-=-=-=-=-=-=-=-=-=-= 这

对Python装饰器的个人理解方法

0.说明 在自己好好总结并对Python装饰器的执行过程进行分解之前,对于装饰器虽然理解它的基本工作方式,但对于存在复杂参数的装饰器(装饰器和函数本身都有参数),总是会感到很模糊,即使这会弄懂了,下一次也很快忘记,其实本质上还是没有多花时间去搞懂其中的细节问题. 虽然网络上已经有很多这样的文章,但显然都是别人的思想,因此自己总是记不牢,所以花点时间自己好好整理一下. 最近在对<Python核心编程>做总结,收获了不少,下面分享一下我自己对于Python装饰器的理解,后面还提供了一个较为复杂的P

[转载]Python装饰器学习(九步入门)

本文转载于: http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print("myfunc() called.") myfunc() myfunc() 第二步:使用装饰函数在函数执行前和执行后分别附加额外功能 # -*- coding:gbk -*- ''

Python装饰器、迭代器&amp;生成器、re正则表达式、字符串格式化

Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########