社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python技巧——装饰器

Python知识驿站 • 3 天前 • 25 次点击  

    在很多时候,我们编写的程序总会有很多的重复代码。比如,我们想记录某个函数的执行时长,保存操作日志等,总是需要在代码中插入相应的代码段。那有没有一种方法,可以解决这部分代码段的频繁修改和插入操作呢?在Python中,为我们提供了一种工具——装饰器,它可以用来提高函数的功能,提高代码的复用度,减少代码冗余。本节就来讲讲装饰器。


<1> 装饰器语法


    装饰器可以认为是一种函数的嵌套,由两层函数嵌套,必须先定义才能使用。首先,来分析下装饰器的语法结构。

    如上所示,定义装饰器方框内:第一行定义了外层decorater(),其括号内制定变量function,目的是将被装饰函数传入内层函数。第二行定义了内层函数inner(),支持变量*args、**args(上节已经说明了意义,这里不缀述)。第三到第五行,是被装饰函数的执行和增强功能。第六行定义内层函数返回值为被装饰函数的返回值,注意该返回值定义错误,将导致被装饰函数无法正常返回指定结果。第七行定义了外层函数的返回值为内存函数名。

    使用装饰器方框内:第一行使用@+装饰器函数名,表示接下来定义的函数将使用装饰器来增强函数功能。第二行及以后,是被装饰函数的编写部分。

    到这里,应该已经明白了装饰器如何定义和使用了。一旦一个函数定义时使用了装饰器,那么后期调用该函数时,装饰器的作用将直接呈现出来。


<2> 时间装饰器


    下面通过代码来演示一个时间装饰器的编写,如下:

# 定义时间装饰器import timedeftimer(function):defdecorater(*args,**kwargs):    t0 = time.time()    result = function(*args,**kwargs)    t1 = time.time()    print('Function name = {0}\nRuntime = {1:.2} seconds'.format(function.__name__,t1-t0))return resultreturn decorater
# 使用装饰器@timerdeftest1():    time.sleep(0.5)
>>> test1()Function name = test1Runtime = 0.5 seconds

    上述代码,通过在内部函数增加了函数执行前后的时间获取,输出了对应函数的输出时长。通过@timer装饰器,我们可以判断被装饰函数的运行时长,从而判断代码效率。

<3> 日志装饰器


    下面通过代码来演示一个日志装饰器的编写,如下:

# 定义日志装饰器import timeimport osdef loger(function):    def decorater(*args,**kwargs):        t0 = time.time()        result = function(*args,**kwargs)        t1 = time.time()        logfile_name = '{0}_log.txt'.format(function.__name__)
# 如果存在日志文件,则直接写入本次log,否则新建文件并写入本次log    if os.path.exists(logfile_name)!=True:        with open(logfile_name,mode='w'as lf:            print('Function name\tRuntime\tResult',file=lf)            print('{0}\t{1:.2}\t{2}'.format(function.__name__,t1-t0,result),file=lf)    else:        with open(logfile_name,mode='a'as lf:            print('{0}\t{1:.2}\t{2}'.format(function.__name__,t1-t0,result),file=lf)
        return result    return decorater
# 使用装饰器@logerdef test2():    time.sleep(0.5)    return'success'
>>> test2()

    打开的日志文档,如下:

    上述代码, 通过在内部函数增加了函数执行前后的时间获取和执行后的日志记录。再利用@loger装饰器,我们可以记录被装饰函数的运行日志,从而方便被装饰函数的问题排查。


<4> 总结


    本节对装饰器的语法结构进行了讲解,并实例演示了时间装饰器和日志装饰器的编写。在实际使用中,我们可以善用装饰器,从而提高代码效率,降低代码冗余度。


-----------------------------

延伸阅读:

    Python入门:第 1 章 Python 介绍

    Python入门:第 2 章 环境搭建与第一个程序

    Python入门:第 3 章 基本语法

    Python入门:第 4 章 数据结构

    Python入门:第 5 章 函数

    Python入门:第 6 章 类

    Python入门:第 7 章 文件读写

    Python入门:第 8 章 Python多进程

    Python入门:第 9 章 进程间通信

    Python入门:第 10 章 消息队列

    自动化办公1——初识Pandas

    自动化办公2——Pandas数据结构

    自动化办公3——Pandas数据操作1

    自动化办公3——Pandas数据操作2

    自动化办公4——Pandas数据组合、连接与重构

    自动化办公5——Pandas数据透视表

     自动化办公6——Pandas数据分组1

    自动化办公6——Pandas数据分组2

    自动化办公7——Pandas画图

    数据可视化——matplotlib基础

    数据可视化——matplotlib进阶

    数据可视化——seaborn初识

    数据可视化——seaborn绘制关系图

    数据可视化——seaborn绘制分布图

    科学计算1——Numpy初识

    科学计算2——Numpy数组操作

    科学计算3——Numpy数组变形

    科学计算4——Numpy的索引与切片

    科学计算5——Numpy的基本计算

    科学计算6——Numpy的矩阵运算

    使用 NumPy 求解线性方程组:一个完整案例


更多内容请查看微信公众号。


---------知识需要分享,需要传播---------

这里是Python知识驿站,致力于知识传播,让更多人了解Python、使用Python、爱上Python。如果你是一名程序员、业余开发者、IT从业者,或者任何一名对Python感兴趣的人,都可以加入Python知识驿站,让我们一同畅享在知识的海洋中。


---------关注我,获得更多知识---------

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/183671
 
25 次点击