python进阶(18)@wraps装饰器[通俗易懂]

python进阶(18)@wraps装饰器[通俗易懂]前言我们都知道装饰器的作用是在不改变原有的代码基础上,添加新的功能,但是这样会有一个弊端,被装饰的函数某些属性会变改变,接下来我们来看下案例importtimedefrun_time(fu

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

我们都知道装饰器的作用是在不改变原有的代码基础上,添加新的功能,但是这样会有一个弊端,被装饰的函数某些属性会变改变,接下来我们来看下
 

案例

import time


def run_time(func):
    def wrapper(*args, **kwargs):
        """时间装饰器"""
        time1 = time.time()
        func(*args, **kwargs)
        time2 = time.time()
        cost_time = time2 - time1
        return f"函数花了{cost_time}秒"
    return wrapper


@run_time
def test():
    """测试"""
    print([i for i in range(1, 100001) if i % 200 == 0])


if __name__ == '__main__':
    print(test.__name__)   
    print(test.__doc__)  
"""
结果
# wrapper
# 时间装饰器
"""

可以看到,我们明明打印的是test函数的__name__属性,最后显示的却是run_time的属性。
 
我们知道@run_time装饰器实际上就等于test = run_time(test),此时我们打印test.__name__实际上test已经指向了wrapper,这样会造成我们打印的时候会打印装饰器的内嵌函数的名字和注释。
 

使用wraps装饰器解决

wraps可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module____name____doc____qualname____annotations__或者通过参数选择

import time
from functools import wraps


def run_time(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """时间装饰器"""
        time1 = time.time()
        func(*args, **kwargs)
        time2 = time.time()
        cost_time = time2 - time1
        return f"函数花了{cost_time}秒"
    return wrapper


@run_time
def test():
    """测试"""
    print([i for i in range(1, 100001) if i % 200 == 0])


if __name__ == '__main__':
    print(test.__name__)   
    print(test.__doc__) 
"""
结果:
test
测试
"""

我们就只在原来的wrapper内函数上加了一个@wraps(func)装饰器,就可以打印出我们想要的结果了,这是因为wraps可以将原函数对象的指定属性复制给包装函数对象,我们可以查看它的源码

def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):
    """Decorator factory to apply update_wrapper() to a wrapper function

       Returns a decorator that invokes update_wrapper() with the decorated
       function as the wrapper argument and the arguments to wraps() as the
       remaining arguments. Default arguments are as for update_wrapper().
       This is a convenience function to simplify applying partial() to
       update_wrapper().
    """
    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/165824.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ActivityManager 讲解

    ActivityManager 讲解1.ActivityManager是android框架的一个重要部分,它负责一新ActivityThread进程创建,Activity生命周期的维护,本blog就是着手对ActivityManager框架作一个整体的了解       2.先看一个静态类结构图:       上图很清楚地描述了ActivityManager框架的几个主要类之间的关系,我们做应用开发接触很多的

    2025年9月25日
    9
  • 分享67套基于Java开发的Java毕业设计实战项目(含源码+毕业论文)【新星计划】

    分享67套基于Java开发的Java毕业设计实战项目(含源码+毕业论文)【新星计划】【新星计划】分享67套基于Java开发的Java毕业设计实战项目(含源码+毕业论文)基于Java开发的Java毕业设计实战项目本文中的所有主题都来自互联网。如果您侵犯您的权利,请及时联系Blogger,博主将及时处理。投诉邮箱:1919101926@qq.com(没事勿扰,不接单,也没时间解决难题,谢谢配合)。文章目录->建议收藏关注+点赞<-基于Java开发的Java毕业设计实战项目前言Java毕业设计所用到的开发环境Java毕业设计项目简单介绍17套基于Java开发的[互

    2022年9月1日
    6
  • python爬虫代码运行_怎么运行python爬虫程序

    python爬虫代码运行_怎么运行python爬虫程序python 爬虫程序运行有两种方式 1 在 python 交互式命令行下直接输入 python 代码回车运行 2 在命令行中使用 python 文件名 py python 运行有两种方式 一种是在 python 交互式命令行下运行 另一种是使用文本编辑器 在命令行中直接运行 注意 以上两种运行方式 都是以 CPython 解释器来编译运行的 当然也可以将 python 代码写入到 eclipse 中 使用 JPython 解

    2025年6月3日
    2
  • c语言处理excel表格_c语言一般文件的处理过程

    c语言处理excel表格_c语言一般文件的处理过程1写excel是.csv后缀,跳跃间隔符是‘\t’ FILE*fp; fp=fopen(“./test.csv”,”w”);//写 for(i=0;i<4;i++) fprintf(fp,”%c,%d,%d\n”,chy[i],data[i],d2); fclose(fp);2读指定位置读数,如倒序读数,从末尾向前读数!先看代码!倒序读最后一行的数据#include<bits/stdc++.h>#define

    2022年8月30日
    6
  • 微型计算机原理与接口技术答案第四版_微机接口与原理技术第三版课后答案

    微型计算机原理与接口技术答案第四版_微机接口与原理技术第三版课后答案微型计算机原理与接口技术第三版答案第1章练习题1.选择题(1)BCA(2)A(3)DA(4)C2.填空(1)10,12(2)取出指令,执行指令(3)(4)内部码3.简答题(1)微处理器,微型计算机和微型计算机系统三者有何联系与区别?答:微处理器是把原来的中央处理单元CPU的复杂电路(包括运算器和控制器)做在一片或…

    2022年10月2日
    4
  • 二叉树及其三种遍历[通俗易懂]

    二叉树及其三种遍历[通俗易懂]一.二叉树的常用性质1.常用性质<1>.在二叉树的第i层上最多有2^(i-1)个节点。(i>=1)<2>.二叉树中如果深度为k(有k层),那么最多有2^k-1个节点。(k>=1)<3>.若二叉树按照从上到下从左到右依次编号,则若某节点编号为k,则其左右子树根节点编号分别为2k和2k+1;<4>.二叉树分类:满二叉树…

    2022年5月6日
    191

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号