zoukankan      html  css  js  c++  java
  • python进阶之装饰器之1.如何定义一个基本的装饰器并使用,保留装饰器的元数据(原信息),逆向解得函数原信息

    本篇文章属于python进阶之装饰器相关的知识的一部分,原文大纲为:https://www.cnblogs.com/max520liuhu/p/9346595.html
    from
    functools import wraps
    #1.定义一个装饰器,此处没有用@wraps
    def my_decorator(func): def wrapper(*args, **kwargs): """decorator""" print('Calling decorated function') return func(*args, **kwargs) return wrapper
    @my_decorator
    def example(): """Docstring""" print('Called example function')
    #输出函数的名字,注释文档信息
    print(example.__name__, example.__doc__) # 输出结果为:wrapper ,decorator,可见函数的信息发生了改变,变成装饰器相关信息 # 2.1使用@wraps,防止在使用装饰器时,函数运行后名称发生变化,示例已表明 def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): """decorator""" print('Calling decorated function...') return func(*args, **kwargs) return wrapper

    @my_decorator
    def example(): """Docstring""" print('Called example function')
    print(example.__name__, example.__doc__) # 输出:example Docstring


    ## 3.示例1
    #编写装饰器,将函数名从右到左,大写的方式打印,编程如下:
    def fuck(func): print("fuck {!s}" .format(func.__name__[::-1].upper())) @fuck def wfg(): pass
    # 以上两个函数代码,执行顺序等同于:wfg=fuck(wfg) #示例2 import time def timethis(func): @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, func.__doc__,func.__annotations__,end-start) return result return wrapper @timethis def countdown(n): while n > 0: n -= 1
      return “hello” print(countdown(1000000))

    #countdown None {} 0.07802963256835938
    #hello
    print(countdown.__name__,countdown.__doc__,countdown.__annotations__)

    #countdown None {}


    ##4.装饰器信息的逆解,通过__wrapped__直接调用未被装饰的函数
    @timethis
    def add(x,y): return x+y or_add = add.__wrapped__ print(or_add(1,2))
    # 直接给出结果:3,装饰器未运行
    print("----------") print(add(1,2))
    #装饰器被调用输出结果如下:
    #add None {} 0.0
    #3

    示例:
    from functools import wraps
    def decorator1(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
    print('Decorator 1')
    return func(*args, **kwargs)
    return wrapper

    def decorator2(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
    print('Decorator 2')
    return func(*args, **kwargs)
    return wrapper

    @decorator1
    @decorator2
    def add(x, y):
    return x + y

    print(add(2, 3))
    #输出:

      Decorator 1
      Decorator 2
      5

    print(add.__wrapped__(2, 3))
    输出:
    5
    仙衣眠云碧岚袍,一襟潇洒,两袖飘飘。玉墨舒心春酝瓢,行也逍遥,坐也逍遥。
  • 相关阅读:
    用Azure VM + Azure Database for MySQL搭建Web服务
    Azure镜像的跨区域复制—Shared Image Gallery(共享映像库)初探
    Azure上几种常见的VM复制操作
    Exchange 2016与国内版O365混合部署(6):混合后的操作和验证
    Exchange 2016与国内版O365混合部署(5):运行AAD Connect及混合部署向导
    Exchange 2016与国内版O365混合部署(4):配置Exchange 公网证书
    Exchange 2016与国内版O365混合部署(3):安装Exchange2016并配置邮件的外网收发
    Exchange 2016与国内版O365混合部署(2):搭建域环境
    Exchange 2016与国内版O365混合部署(1):过程总览
    Cross-Tanant 步骤
  • 原文地址:https://www.cnblogs.com/max520liuhu/p/9346870.html
Copyright © 2011-2022 走看看