Python 在函数上添加包装器

 更新时间:2020年07月28日 10:31:10   作者:看云  
这篇文章主要介绍了Python 如何在函数上添加包装器,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

问题

你想在函数上添加一个包装器,增加额外的操作处理(比如日志、计时等)。

解决方案

如果你想使用额外的代码包装一个函数,可以定义一个装饰器函数,例如:

import time
from functools import wraps

def timethis(func):
  '''
  Decorator that reports the execution time.
  '''
  @wraps(func)
  def wrapper(*args, **kwargs):
    start = time.time()
    result = func(*args, **kwargs)
    end = time.time()
    print(func.__name__, end-start)
    return result
  return wrapper

下面是使用装饰器的例子:

>>> @timethis
... def countdown(n):
...   '''
...   Counts down
...   '''
...   while n > 0:
...     n -= 1
...
>>> countdown(100000)
countdown 0.008917808532714844
>>> countdown(10000000)
countdown 0.87188299392912
>>>

讨论

一个装饰器就是一个函数,它接受一个函数作为参数并返回一个新的函数。当你像下面这样写:

@timethis
def countdown(n):
  pass

跟像下面这样写其实效果是一样的:

def countdown(n):
  pass
countdown = timethis(countdown)

顺便说一下,内置的装饰器比如 @staticmethod, @classmethod,@property 原理也是一样的。例如,下面这两个代码片段是等价的:

class A:
  @classmethod
  def method(cls):
    pass

class B:
  # Equivalent definition of a class method
  def method(cls):
    pass
  method = classmethod(method)

在上面的 wrapper() 函数中,装饰器内部定义了一个使用 *args 和 **kwargs 来接受任意参数的函数。在这个函数里面调用了原始函数并将其结果返回,不过你还可以添加其他额外的代码(比如计时)。然后这个新的函数包装器被作为结果返回来代替原始函数。

需要强调的是装饰器并不会修改原始函数的参数签名以及返回值。使用 *args 和 **kwargs 目的就是确保任何参数都能适用。而返回结果值基本都是调用原始函数 func(*args, **kwargs) 的返回结果,其中func就是原始函数。

刚开始学习装饰器的时候,会使用一些简单的例子来说明,比如上面演示的这个。不过实际场景使用时,还是有一些细节问题要注意的。比如上面使用 @wraps(func) 注解是很重要的,它能保留原始函数的元数据(下一小节会讲到),新手经常会忽略这个细节。接下来的几个小节我们会更加深入的讲解装饰器函数的细节问题,如果你想构造你自己的装饰器函数,需要认真看一下。

以上就是Python 在函数上添加包装器的详细内容,更多关于Python 添加包装器的资料请关注脚本之家其它相关文章!

相关文章

  • Python技巧分享之如何将字符串转回DataFrame格式

    Python技巧分享之如何将字符串转回DataFrame格式

    平常我们使用pandas,一般使用的是DataFrame和Series,但个别交换数据的时候,只能使用字符串,那如何再将字符串再转回DataFrame格式呢,本文就来和大家讲讲解决办法
    2023-06-06
  • pandas参数设置的实用小技巧

    pandas参数设置的实用小技巧

    这篇文章主要给大家介绍了关于pandas参数设置的实用小技巧,文中通过实例代码结束的非常详细,对大家学习或者使用pandas具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-08-08
  • 一文带你了解Python中pymysql的使用

    一文带你了解Python中pymysql的使用

    pymysql就是联通mysql实现python窗口与mysql数据库交互的库,十分方便操作,这篇文章将详细说明如何掌握并使用该库,感兴趣的可以了解一下
    2023-02-02
  • python机器学习之线性回归详解

    python机器学习之线性回归详解

    这篇文章主要介绍了python机器学习之线性回归详解,文中有非常详细的代码示例,对正在学习python的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-04-04
  • python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例

    python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例

    这篇文章主要介绍了python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例,需要的朋友可以参考下
    2020-02-02
  • 使用Python编写Linux系统守护进程实例

    使用Python编写Linux系统守护进程实例

    这篇文章主要介绍了使用Python编写Linux系统守护进程实例,本文先是讲解了什么是守护进程,然后给出了一个Python语言的简单实现,需要的朋友可以参考下
    2015-02-02
  • Python中的二叉树查找算法模块使用指南

    Python中的二叉树查找算法模块使用指南

    二叉树查找算法,在开发实践中,会经常用到。按照惯例,对于这么一个常用的东西,Python一定会提供轮子的。是的,python就是这样,一定会让开发者省心,降低开发者的工作压力。
    2014-07-07
  • python 内置库wsgiref的使用(WSGI基础入门)

    python 内置库wsgiref的使用(WSGI基础入门)

    WSGI(web服务器网关接口)主要规定了服务器端和应用程序之间的接口,即规定了请求的URL到后台处理函数之间的映射该如何实现。wsgiref是一个帮助开发者开发测试的Python内置库,程序员可以通过这个库了解WSGI的基本运行原理,但是不能把它用在生产环境上。
    2021-06-06
  • 使用Python中的线程进行网络编程的入门教程

    使用Python中的线程进行网络编程的入门教程

    这篇文章主要介绍了使用Python中的线程进行网络编程的入门教程,本文来自于IBM官方网站技术文档,需要的朋友可以参考下
    2015-04-04
  • Python面向对象中的封装详情

    Python面向对象中的封装详情

    这篇文章主要介绍了Python面向对象中的封装详情,在python中也有对对象的封装操作,使其对外只提供固定的访问模式,不能访问其内部的私有属性和私有方法。下文详细内容,需要的小伙伴可以参考一下
    2022-03-03

最新评论