python2装饰器_python函数装饰器

python2装饰器_python函数装饰器前言我们都知道装饰器的作用是在不改变原有的代码基础上,添加新的功能,但是这样会有一个弊端,被装饰的函数某些属性会变改变,接下来我们来看下案例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/165479.html原文链接:https://javaforall.net

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


相关推荐

  • navicat for mysql 15激活码_在线激活2022.01.18

    (navicat for mysql 15激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html0HKLM1UCCY-eyJsaWNlbnNlSW…

    2022年3月31日
  • 基于OIDC实现单点登录SSO、第三方登录[通俗易懂]

    基于OIDC实现单点登录SSO、第三方登录[通俗易懂]OIDC联合身份认证机制背景概念1OIDC身份认证协议2基于OIDC实现SSO2.1统一登录2.1.1流程2.1.2RP相关接口2.1.3OP相关接口2.2统一登出2.2.1流程2.2.2RP需要在向OP注册时提供2.2.3RP相关接口2.2.4OP相关接口2.3持续监视2.3.1流程2.3.2RP相关接口2.3.3OP相关接口3在OIDC的SSO中集成第三方登录(…

    2022年8月30日
  • STM32之HAL库的串口接收丢字节_stm32标准库还有更新吗

    STM32之HAL库的串口接收丢字节_stm32标准库还有更新吗1STM32的三种开发方式通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配置寄存器进行开发。网上关于标准库、HAL库的描述相信是数不胜数。可是一个对于很多刚入门的朋友还是没法很直观的去真正了解这些不同开发发方式彼此之间的区别,所以笔者想以一种非常直白的方式,用自己的理解…

    2022年9月3日
  • 博弈论三个枪手的故事_博弈模型的三个基本要素

    博弈论三个枪手的故事_博弈模型的三个基本要素彼此痛恨的甲、乙、丙三个枪手准备决斗。甲枪法最好,十发八中;乙枪法次之,十发六中;丙枪法最差,十发四中。先提第一个问题:如果三人同时开枪,并且每人只发一枪;第一轮枪战后,谁活下来的机会大一些?一般人认为甲的枪法好,活下来的可能性大一些。但合乎推理的结论是,枪法最糟糕的丙活下来的几率最大。我们来分析一下各个枪手的策略。枪手甲一定要对枪手乙先开枪。因为乙对甲的威胁要比丙对甲的威胁更大,甲应该首…

    2022年10月15日
  • Linux通配符摘要

    Linux通配符摘要

    2021年12月30日

发表回复

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

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