Python装饰器举例分析

栏目: Python · 发布时间: 6年前

内容简介:Python装饰器举例分析

概述

装饰器本质上是一个 Python 函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

我们要需要一个能测试函数运行时间的decorator,可以定义如下:

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print("Run time is: %s" % (end_time - start_time))
        return res
    return wrapper

因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。 我们要借助Python的@语法 ,把decorator置于函数的定义处:

@timer
def fun():
    time.sleep(1)
    print("This is a test")
    return "OK"

运行结果就是:

This is a test
Run time is: 1.0000572204589844
OK

把@timer放在fun ()处就相当于执行了语句:

fun = timer(fun)

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,比如加上名字:

def timer(name):
    def decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            end_time = time.time()
            print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
            return res
        return wrapper
    return decorator

调用及结果显示如下:

@timer("Lance#")
def fun():
    time.sleep(1)
    print("This is a test")
    return "OK"
This is a test
Name is: Lance# ; Run time is: 1.0000572204589844
OK

和两层嵌套的decorator相比,三层嵌套的效果是这样的:

fun = timer("Lance#")(fun)

因为函数也是对象,它也有__name__等属性。

在未加装饰器之前的fun()函数,调用 fun的__name__属性结果是 'fun',但经过decorator装饰之后的函数,它们的__name__已经从原来的'fun'变成了'wrapper'

所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

Python内置的functools.wraps就可以完成这个任务,所以,一个完整的decorator的写法如下:

import functools

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print("Run time is: %s" % (end_time - start_time))
        return res
    return wrapper

整体代码如下:

__Author__ = "Lance#"

# -*- coding = utf-8 -*-

import time
import functools

def timer(name):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = func(*args, **kwargs)
            end_time = time.time()
            print("Name is: %s ; Run time is: %s" % (name, (end_time - start_time)))
            return res
        return wrapper
    return decorator

@timer("Lance#")
def fun():
    time.sleep(1)
    print("This is a test")
    return "OK"

if __name__ == '__main__':
    print(fun())

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

推荐系统与深度学习

推荐系统与深度学习

黄昕、赵伟、王本友、吕慧伟、杨敏 / 清华大学出版社 / 2019-1-1 / 65.00元

本书的内容设置由浅入深,从传统的推荐算法过渡到近年兴起的深度学习技术。不管是初学者,还是有一定经验的从业人员,相信都能从本书的不同章节中有所收获。 区别于其他推荐算法书籍,本书引入了已被实践证明效果较好的深度学习推荐技术,包括Word2Vec、Wide & Deep、DeepFM、GAN 等技术应用,并给出了相关的实践代码;除了在算法层面讲解推荐系统的实现,还从工程层面详细阐述推荐系统如何搭建.一起来看看 《推荐系统与深度学习》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具