Python之装饰器

一、啥是装饰器

  Python中的装饰器就是对函数的装饰作用,对函数的执行,做了一些装饰,比方说人还是那个人,不过做了一些打扮修饰。装饰器本身也是函数,不过它可以对别的函数进行装饰,参数必须是函数

二、为啥要整个装饰器?

  北京的雾霾天,大家都要带着口罩出门。函数都要额外装饰一下,比如统计运算的时间啦,做一些记录啦~~~等等。我们只需要做一个口罩,需要的函数只需要往自己脸上一带,就可以啦!

三、装饰器遵循的原则:

  1、被装饰的函数不能修改:这个大家都懂,装饰器仅仅是装饰,当然不能改变原来的函数的代码(开放封闭原则),任何函数都可以用(开放),都不必关心(内部如何实现)

  2、被装饰的函数的调用方式不能改变:一样一样的,原来的函数该咋使用还得继续咋使用,不能被装饰了就变了

四、实现原理:

  装饰器:高阶函数 + 函数嵌套 + 闭包

  听着很高深而已

  高阶函数:函数也是个对象,可以作为参数传递,还可以return返回一个函数

  函数嵌套:函数里面还可以有函数

  闭包:闭起来的包,就是局部变量的啦~~~

五、无参的装饰器装饰无参的函数(就是最简单的,都木有参数)

一层就够了,把要装饰的函数扔进去就够了

#!/usr/bin/env python
# -*- coding: utf8 -*-
# __Author: "Skiler Hao"
# date: 2017/4/24 20:50
import functools
import time

def timer(func):
    """
    一个可以计算函数运行时间的装饰器
    :param func:
    :return:
    """
    @functools.wraps(func)
    def wrapper():
        start_time=time.time()   # 函数开始执行时间戳

        res=func()  # 被装饰的函数的本身的执行,其余的都属于装饰内容

# 函数执行结束的时间戳 stop_time=time.time() # 仅仅做打印而已 print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time)) # 将结果一层层返回,一点都不影响被装饰的函数,只是被装饰计算并打印时间而已

return res # 将被装饰函数的结果一步步向外返回,不影响被装饰函数的值的返回 return wrapper @timer def sleep3s(): """ 睡三秒函数 :return: """ time.sleep(3) return '哈哈,不小心睡了三秒!' sleep3s_str = sleep3s() print(sleep3s_str) # 函数[<function sleep3s at 0x012DCDF8>],运行时间是[3.0001559257507324] # 哈哈,不小心睡了三秒!

 

 六、无参装饰器装饰有参数的函数

最少得两层,一层放函数,一层放被装饰的函数的参数

#!/usr/bin/env python
# -*- coding: utf8 -*-
# __Author: "Skiler Hao"
# date: 2017/4/24 20:50
import functools

import time


def timer(func):
    """
    一个可以计算函数运行时间的装饰器
    :param func:
    :return:
    """
    @functools.wraps(func)
    def wrapper(*args,**kwargs):

        # 函数开始执行时间戳
        start_time=time.time()
        # 执行func也就是被装饰的函数
        res=func(*args,**kwargs)  # 将原来函数的执行结果给res

        # 函数执行结束的时间戳
        stop_time=time.time()
        # 仅仅做打印而已
        print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
        # 将结果一层层返回,一点都不影响被装饰的函数,只是被装饰计算并打印时间而已
        return res
    return wrapper


@timer
def sleep3s(name = 'Skiler'):
    """
    睡三秒函数
    :return:
    """
    print(name + '要睡着了!')
    time.sleep(3)
    return '哈哈,不小心睡了三秒!'

sleep3s_str = sleep3s(name='Hao')
print(sleep3s_str)

# Hao要睡着了!
# 函数[<function sleep3s at 0x0155CDF8>],运行时间是[3.0009310245513916]
# 哈哈,不小心睡了三秒!

 七、有参装饰器:(什么意思,就是装饰器也可以带参数,纳尼~~~)

最少得三层:一层:自己的参数;二层:被装饰的函数;三层: 被装饰的函数的参数

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@log('随便说点!')
def say_hi(name, to):
    print(name + ':' + to + ',hi!美女')


say_hi('Skiler', '刘亦菲')

# 随便说点! say_hi():
# Skiler:刘亦菲,hi!美女

 

posted @ 2017-04-24 08:49  skiler  阅读(184)  评论(0)    收藏  举报