如何实现一个python函数装饰器(Decorator)

 更新时间:2020年10月12日 09:13:14   作者:半杯茶的小酒杯  
这篇文章主要介绍了如何实现一个python函数装饰器(Decorator),帮助大家更好的理解和学习python,感兴趣的朋友可以了解下

装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。它经常用于为已有函数/类添加记录日志、计时统计、性能测试等。

首先定义一个倒计时函数,这个函数的功能非常简单,就是把n从当前值减少到0。

def countdown(n):
 while n > 0:
  print('time' + str(n))
  n -= 1

print(countdown.__name__)

程序输出:

countdown

1.为函数增加一个日志装饰器

假设现在要增强countdown的功能,在函数调用前后自动打印日志,又不想修改函数自身的功能。这种在代码运行期间动态增加功能的方式,称之为装饰器(Decorator)。

能打印日志的decorator,可以定义如下:

def log(func):
  def wrapper(*args, **kw):
    print('call %s().' % func.__name__)
    return func(*args, **kw)
  return wrapper

然后我们借助Python的@语法,把decorator置于函数的定义处:

@log
def countdown(n):
 while n > 0:
  print('time:' + str(n))
  n -= 1

countdown(10)

程序输出:

call countdown().
time:10
time:9
time:8
time:7
time:6
time:5
time:4
time:3
time:2
time:1

但此时我们再打印函数的name:

print(countdown.__name__)

程序输出:

wrapper

我们发现函数的元数据信息变了,这显然不是我们想要的结果。

2. 在装饰器中拷贝元数据

为了把函数的元数据信息都保留下来,我们可以直接使用Python提供的functools库中的@wraps装饰器。

from functools import wraps

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

@log
def countdown(n):
 while n > 0:
  print('time:' + str(n))
  n -= 1

print(countdown.__name__)

程序输出:

countdown

3.为函数增加一个计时装饰器

添加函数装饰器的方法已经讲清楚了,现在再实现一个完整的函数计时耗时装饰器。

import time
from functools import wraps

def TimeCost(func):
 @wraps(func)
 def wrapper(*arg, **kwargs):
  start = time.time()
  result = func(*args, **kwargs)
  end = time.time()
  print(func.__name__, end - start)
  return result
 return wrapper

@TimeCost
def countdown(n):
 while n > 0:
  print('time:' + str(n))
  n -= 1

countdown(10000)

函数输出:

('countdown', 0.0004801750183105469)

参考资料:

https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584

Python Cookbook中文版

以上就是如何实现一个python函数装饰器(Decorator)的详细内容,更多关于python函数装饰器的资料请关注脚本之家其它相关文章!

相关文章

  • python简单获取数组元素个数的方法

    python简单获取数组元素个数的方法

    这篇文章主要介绍了python简单获取数组元素个数的方法,实例分析了Python中len方法的相关使用技巧,非常简单实用,需要的朋友可以参考下
    2015-07-07
  • 如何通过一篇文章了解Python中的生成器

    如何通过一篇文章了解Python中的生成器

    生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象,下面这篇文章主要给大家介绍了关于Python中生成器的相关资料,需要的朋友可以参考下
    2022-04-04
  • 详解Python3 定义一个跨越多行的字符串的多种方法

    详解Python3 定义一个跨越多行的字符串的多种方法

    这篇文章主要介绍了详解Python3 定义一个跨越多行的字符串的多种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 浅谈Python中的zip()与*zip()函数详解

    浅谈Python中的zip()与*zip()函数详解

    这篇文章主要介绍了浅谈Python中的zip()与*zip()函数详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • 使用pandas生成/读取csv文件的方法实例

    使用pandas生成/读取csv文件的方法实例

    在使用Pandas处理数据时,常见的读取数据的方式时从Excel或CSV文件中获取,这篇文章主要给大家介绍了关于如何使用pandas生成、读取csv文件的相关资料,需要的朋友可以参考下
    2021-07-07
  • 原来我一直安装 Python 库的姿势都不对呀

    原来我一直安装 Python 库的姿势都不对呀

    平常我都是直接执行 pip install 安装的第三方库,很多教程也是这么介绍的,一直以来我都认为这是标准的、正确的安装 Python 第三方库的姿势。下面小编给大家分享一篇教程,一起看看吧
    2019-11-11
  • 利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式

    利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式

    今天小编就为大家分享一篇利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • python数据结构:数据类型

    python数据结构:数据类型

    这篇文章主要介绍了python数据结构中的数据类型,在 Python 以及其他所有面向对象编程语言中,类都是对数据的构成(状态)以及数据 能做什么(行为)的描述,下面我们就来你看看python数据结构中的数据类型商务详细介绍,需要的小伙伴可以参考一下
    2021-12-12
  • Pytest测试框架基本使用方法详解

    Pytest测试框架基本使用方法详解

    这篇文章主要介绍了Pytest测试框架基本使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Python深入学习之特殊方法与多范式

    Python深入学习之特殊方法与多范式

    这篇文章主要介绍了Python深入学习之特殊方法与多范式,特殊方法就像PHP里的魔术方法,多范式是指可以用面向对象、面向过程、函数式、声明式等方式编写程序,需要的朋友可以参考下
    2014-08-08

最新评论