Python 装饰器

印象笔记复制过来格式惨不忍睹,装饰器的知识是从赖大那里偷来的,推荐赖大的博客:http://mingxinglai.com
1.装饰器的概念
2.装饰器的四个注意事项
3.装饰器的缺点
 
装饰器的概念
1.Python2.4开始提供了装饰器(decorator),装饰器作为修改函数的一种便捷方式,为程序员编写程序提供了便利性和灵活性。
装饰器的本质上就是一个函数,这个函数接收其他函数作为参数,并将其以一个新的修改后的函数进行替换。
 
装饰器是Python提供给我们的语法糖
def bread(func):
    def wrapper():
        print "-------"
        func()
        print "-------"
    return wrapper
 
sandwich_copy = bread(sandwich)
sandwich_copy()
def bread(func):
    def wrapper():
        print "-----"
        func()
        print "-----"
    return wrapper
 
@bread
def sandwich(food="--ham--"):
    print food
 
2.涉及到几个知识点:
    函数嵌套
    函数就是对象(函数对象),可以随意传递
    语法糖:语言自身提供,用更加简便的方式表示某种行为
 
3.装饰器的使用场景:
1.注入参数(提供默认参数,生成参数)
2.记录函数行为(日志、缓存、计时)
3.预处理/后处理(配置上下文)
4.修改调用时的上下文(线程异步或者并行,类方法)
 
benchmark
import time
def benchmark(func):
    def wrapper(*args,**keargs):
        t = time.clock()
        res = func(*args,**kwargs)
        print(func.__name__,time.clock() -t)
        return res
    return wrapper
 
装饰器的注意事项
1.函数的属性变化
2.使用inspect获取函数参数
3.多个装饰器的调用顺序
4.给装饰器传递参数
 
1.如果不实用@functools.wraps(f),函数的属性会丢失
 
  4 from __future__ import print_function
  5 import functools
  6
  7 def is_admin(f):
  8     @functools.wraps(f)
  9     def wrapper(*args,**kwargs):
10         if kwargs.get('username') != 'admin':
11             raise Exception('This user is not allowed to get food')
12         return f(*args,**kwargs)
13     return wrapper
14
15 def foobar(username = 'someone'):
16     '''Do crazy stuff'''
17     pass
18
19 @is_admin
20 def barfoo(username = 'someone'):
21     '''Do crazy stuff'''
22     pass
23
24 print(foobar.func_doc)
25 print(foobar.__name__)
26 print(barfoo.func_doc)
27 print(barfoo.__name__)
 
2.使用inspect获取函数参数
 
inspect.getcallargs(f,*args,**kwargs)自动推断参数对应位置,并总是返回一个字典,这个字典包含了所有的参数
 
3.多个装饰器的调用顺序,越靠近函数的越先调用
 
4.给装饰器传递参数:三层封装即可
 
  2 from __future__ import print_function
  3
  4 def times(length=2):
  5     def decorator(func):
  6         def wrapper(*args,**kwargs):
  7             for i in range(length):
  8                 func(*args,**kwargs)
  9         return wrapper
10     return decorator
11                                                                                          
12 @times(5)
13 def sandwich():
14     print('beef')
15     
16 sandwich()
 
 
装饰器的缺点:
1.装饰器封装的越多,性能就越差,但是一般易用性会更好
2.封装越复杂,越难以调试
3.只能装饰,不能反装饰
 
 
装饰器的概念 装饰器的四个注意事项 装饰器的缺点
装饰器的四个注意事项:
函数属性的变化 使用inspect获取函数参数 多个装饰器的调用顺序 给装饰器传递参数
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted on 2017-12-18 17:57  izongjun  阅读(206)  评论(0编辑  收藏  举报