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

 

posted @ 2018-07-21 15:38  神毓·逍遥  阅读(184)  评论(0编辑  收藏  举报