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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 原码补码相互转换[通俗易懂]

    原码补码相互转换[通俗易懂]1.基础概念原码:为十进制数的二进制表示,正数符号位为0,负数符号位为1例如:10的二进制为00001010,-10的二进制为10001010补码:为原码的计算码,通俗的讲,计算的时候用补码,看大小的时候用原码2.原码转换成补码正数原码转补码:正数的补码,与原码相同例如,10的原码为00001010,补码也是00001010负数原码转补码:负数的补码:符号位不变,其余各位按位取反,取反后整体加1例如:-10的原码为10001010…

    2022年10月28日
    0
  • php采集程序的方法有哪些_php采集插件

    php采集程序的方法有哪些_php采集插件php采集程序的方法在我们程序开发的过程中是经常要遇到的,那我们常用的采集方法有哪些呢,下面我们一起来看具体的方法,还附带有具体实例,让大家一看就明白,会用。方法一:file_get_contents($url);$url=”http://www.seostudying.com”;$con=file_get_contents($url); //采集到的内容将存储到$c

    2025年6月8日
    0
  • pycharm的配置_pycharm怎么配置python环境变量

    pycharm的配置_pycharm怎么配置python环境变量一、Python解释器1、Python解释器计算机只能读懂0和1这样的二进制编码文件,所以需要一个东西将Python程序解释成计算机可以读懂并执行的二进制文件,这个东西就是Python解释器。在PyCharm中运行Python代码,您需要配置至少一个Python解释器。PyCharm支持以下解释器类型: 源Python解释器; 虚拟环境:(Virtualenv,Pipenv,andConda); 其他Python实现(IronP.

    2022年8月28日
    0
  • 8086汇编翻译机器码_8086汇编编程手册

    8086汇编翻译机器码_8086汇编编程手册汇编指令与机器码的相互转换 贴子发表于:2008-10-2812:48:03 机器语言我们只要重点理解一下几个概念:1.机器语言指令有操作码(OP)和地址码两部分组成|_____________OP_______________|__d__|__w__||_____________OP_______________|__s__|__w__|在多数操作码中,常使用某些位来

    2022年10月7日
    0
  • cnpm安装和使用[通俗易懂]

    cnpm安装和使用[通俗易懂]在已经安装node.js基础上,利用npm来安装cnpm。cnpm是利用淘宝镜像来安装依赖包!优点:会比npm安装来的速度更快  操作:1、全局安装cnpm,打开cmd输入:npmi-gcnpm 2、验证是否安装成功,可以通过查看版本:cnpmversion当出现如下版本号,表示安装成功 …

    2022年10月10日
    0
  • 分布式 – 公司使用什么RPC框架,聊聊你理解的RPC原理

    分布式 – 公司使用什么RPC框架,聊聊你理解的RPC原理不啰嗦,我们直接开始!引言以前在做一个规模不大的系统的时候,用的是单体架构,一台服务器部署上一个应用和数据库也就够了。但是现代化互联网公司业务逐渐扩大,服务逐渐细分,很多服务之间需要通过远程分布式接口调用通讯,即不同的服务不是部署在同一个服务器上,比如订单服务在A服务上,付款服务在另一个服务上,有同步调用、也有异步调用,这个时候我们就需要远程调用不同的服务,使用的时候调用远程服务就像调用本地服务一样,引入一个jar包,就能通过this.xxx()一样调用远程服务,这背后的机制就是通.

    2022年5月12日
    30

发表回复

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

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