当前位置: 首页 > news >正文

包装函数 python_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博客其它相关文章!

相关文章:

  • kirin710f是什么处理器_麒麟710F处理器怎么样
  • epoll编程实例客户端_socket采用epoll编程demo
  • pythonsvd内存不足_python – 有没有办法防止numpy.linalg.svd内存不足?
  • python 统计分析apache日志_Apache 日志分析(一)
  • mysql中groupby会用到索引吗_MySQL优化GROUP BY方案
  • php5.6的apaches的dll_win7(64位)php5.6-Apache2.4-mysql5.6环境安装
  • freemarker反向取数_freemarker 取值(插值)(转)
  • miui 谷歌框架_谷歌和高通正式联手,加强安卓系统掌控,华为:鸿蒙正全面超越...
  • python 随机打乱列表_python打乱列表
  • 图片画圈画箭头用什么软件_什么软件可以在编辑图片中画圈圈,如裁图时需要特..._网络编辑_帮考网...
  • 0 win10重装partition_gpt分区无法安装win10的根本原因
  • python csv库下载_Python标准库--csv模块
  • kafka身份认证 maxwell_python – kafka身份验证和授权
  • python类的封装是什么意思_Python中什么是面向对象-封装
  • 瑞银监控机器人组装法_“机器人革命”来了!瑞银计划年内再扩充400台自动化机器人...
  • [deviceone开发]-do_Webview的基本示例
  • 【翻译】babel对TC39装饰器草案的实现
  • 2017届校招提前批面试回顾
  • CEF与代理
  • Java 23种设计模式 之单例模式 7种实现方式
  • nodejs实现webservice问题总结
  • orm2 中文文档 3.1 模型属性
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 技术胖1-4季视频复习— (看视频笔记)
  • 配置 PM2 实现代码自动发布
  • 如何在GitHub上创建个人博客
  • 移动端唤起键盘时取消position:fixed定位
  • 正则与JS中的正则
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 交换综合实验一
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​批处理文件中的errorlevel用法
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # Maven错误Error executing Maven
  • #Linux(Source Insight安装及工程建立)
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • #预处理和函数的对比以及条件编译
  • $.proxy和$.extend
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (二)hibernate配置管理
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (一)插入排序
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • .net core 连接数据库,通过数据库生成Modell
  • .NET MVC之AOP
  • .Net的C#语言取月份数值对应的MonthName值
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET中GET与SET的用法
  • @Conditional注解详解
  • []C/C++读取串口接收到的数据程序