Python装饰器的理解

Python装饰器是什么

Python装饰器就是一个函数,它的产生是为了在不改变目标函数结构的基础上为其增加功能,返回值是增加功能后的目标函数。

一个简单的装饰器 -为程序添加简单的计时功能

import time

def get_run_time(method):
    def wrapper():
        start = time.time()
        method()
        end = time.time()
        return end - start
    return wrapper

@get_run_time
def helloworld():
    print('helloworld')

if __name__ == '__main__':
    spend = helloworld()
    print('spend time: {}'.format(spend))

运行结果:

... 
helloworld
spend time: 1.50203704834e-05

目标函数带参数的情况

当然有时候目标函数(在上面的程序中为helloworld函数)是有参数的,下面做一些微小的改动

import time

def get_run_time(method):
    def wrapper(*args, **kwargs):
        start = time.time()
        method(*args, **kwargs)
        end = time.time()
        return end - start
    return wrapper

@get_run_time
def helloworld(name):
    print('I\'m {}, helloworld'.format(name))

if __name__ == '__main__':
    spend = helloworld('wk')
    print('spend time: {}'.format(spend))

运行结果:

... 
I'm wk, helloworld
spend time: 2.09808349609e-05

装饰器函数带参数的情况

既然装饰器是个函数,那它也是可以有参数的,此时只要将上述代码稍加改动即可

import time

def get_run_time(decimal):
    def wrapper_of_wrapper(method):
        def wrapper(*args, **kwargs):
            start = time.time()
            method(*args, **kwargs)
            end = time.time()
            return round(end - start, decimal)
        return wrapper
    return wrapper_of_wrapper

@get_run_time(decimal=16)
def helloworld(name):
    print('I\'m {}, helloworld'.format(name))

if __name__ == '__main__':
    spend = helloworld('wk')
    print('spend time: {}'.format(spend))
    # 下面这行先不用看,这是下一个标题的内容
    print(helloworld.__name__)

增加了控制返回时间精度的功能,其实就是在原基础上多封了一层,最外层是新增的一层,目的是增加一个相对全局变量(能看懂就行了,能力有限,就不扯深的了),在上述代码中是decimal

执行结果:

... 
I'm wk, helloworld
spend time: 4.60147857666e-05
wrapper

@functools.wraps

装饰器返回的函数虽然结构与目标函数相似,但本质已经发生了变话,返回的是另一个函数,看上面程序中print(helloworld.__name__)的输出为wrapper,再看看functools.wraps的效果

import time
import functools

def get_run_time(decimal):
    def wrapper_of_wrapper(method):
        @functools.wraps(method)
        def wrapper(*args, **kwargs):
            start = time.time()
            method(*args, **kwargs)
            end = time.time()
            return round(end - start, decimal)
        return wrapper
    return wrapper_of_wrapper

@get_run_time(decimal=16)
def helloworld(name):
    print('I\'m {}, helloworld'.format(name))

if __name__ == '__main__':
    spend = helloworld('wk')
    print('spend time: {}'.format(spend))
    # 对比一下,只增加了@functools.wraps
    print(helloworld.__name__)

运行结果:

... 
I'm wk, helloworld
spend time: 2.09808349609e-05
helloworld
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值