简单的装饰器进阶

本文探讨了Python中使用装饰器时如何保持被装饰函数的元数据,如名称和文档字符串不变。通过三种方法:手动复制、使用copysrc函数和利用functools.wraps,展示了如何避免装饰器对函数元数据的影响。
摘要由CSDN通过智能技术生成
创建一个装饰器,要求打印元数据的DOC和NAME属性
import datetime,time

def loog(fn):
    def wrapper(*args,**kwargs):
        print("{} program start".format(fn.__name__))
        start = datetime.datetime.now()
        cc = fn(*args,**kwargs)
        delta = (datetime.datetime.now()-start).total_seconds()
        print("{} program end it took {} seconds".format(fn.__name__,delta))
    return wrapper

@loog  # add = loog(add)
def add(x, y):
    """I am a function ..."""
    time.sleep(1)
    return x + y

add(5,8)
print("function name is {},function doc is {}".format(add.__name__,add.__doc__))
调用函数进行属性覆盖
import datetime,time,functools

def copysrc(src):
    def _copy(dest):
        dest.__name__ = src.__name__
        dest.__doc__ = src.__doc__
        return dest
    return _copy

def loog(fn):
    def wrapper(*args,**kwargs):
        print("{} program start".format(fn.__name__))
        start = datetime.datetime.now()
        cc = fn(*args,**kwargs)
        delta = (datetime.datetime.now()-start).total_seconds()
        print("{} program end it took {} seconds".format(fn.__name__,delta))
        copysrc(fn)(wrapper)                                                 #调用函数copysrc进行属性的覆盖
    return wrapper

@loog  # add = loog(add)
def add(x, y):
    """I am a function ..."""
    time.sleep(1)
    return x + y
add(5, 8)
print("function name is {},function doc is {}".format(add.__name__,add.__doc__))
装饰器装饰装饰器
import datetime,time,functools

def copysrc(src):
    def _copy(dest):
        dest.__name__ = src.__name__
        dest.__doc__ = src.__doc__
        return dest
    return _copy

def loog(fn):
    @copysrc(fn)  # wrapper = copysrc(fn)(wrapper)
    def wrapper(*args,**kwargs):
        print("{} program start".format(fn.__name__))
        start = datetime.datetime.now()
        cc = fn(*args,**kwargs)
        delta = (datetime.datetime.now()-start).total_seconds()
        print("{} program end it took {} seconds".format(fn.__name__,delta))
    return wrapper

@loog  # add = loog(add)
def add(x, y):
    """I am a function ..."""
    time.sleep(1)
    return x + y

add(5,8)
print("function name is {},function doc is {}".format(add.__name__,add.__doc__))
用functools 模块进行装饰
import datetime,time,functools

# def copysrc(src):
#     def _copy(dest):
#         dest.__name__ = src.__name__
#         dest.__doc__ = src.__doc__
#         return dest
#     return _copy

def loog(fn):
    @functools.wraps(fn) # 等效于 wrapper = copysrc(fn)(wrapper)                          # 调用wraps函数进行装饰
    def wrapper(*args,**kwargs):
        """My name is wrapper"""
        print("{} program start".format(fn.__name__))
        start = datetime.datetime.now()
        cc = fn(*args,**kwargs)
        delta = (datetime.datetime.now()-start).total_seconds()
        print("{} program end it took {} seconds".format(fn.__name__,delta))
        return cc
    return wrapper

@loog  # add = loog(add)
def add(x, y):
    """I am a function ..."""
    time.sleep(1)
    return x + y

add(5,8)
print("function name is {},function doc is {}".format(add.__name__, add.__doc__))
用functools 模块进行装饰
import datetime,time,functools

# def copysrc(src):
#     def _copy(dest):
#         dest.__name__ = src.__name__
#         dest.__doc__ = src.__doc__
#         return dest
#     return _copy

def test(flag):
    def loog(fn):
        @functools.wraps(fn) # 等效于 wrapper = copysrc(fn)(wrapper)
        def wrapper(*args,**kwargs):
            """My name is wrapper"""
            print("{} program start".format(fn.__name__))
            print("args = {},kwargs = {}".format(args,kwargs))
            start = datetime.datetime.now()
            cc = fn(*args,**kwargs)
            delta = (datetime.datetime.now()-start).total_seconds()
            print("{} program end it took {} seconds".format(fn.__name__,delta))
            print("{} too slow".format(fn.__name__) if delta > flag else "{} OK ,is fast".format(fn.__name__))
            return cc
        return wrapper
    return loog

@test(2)  # add = loog(add)
def add(x, y,z=2):
    """I am a function ..."""
    time.sleep(1)
    return x + y

add(5,8,z=15)
print("function name is {},function doc is {}".format(add.__name__,add.__doc__))
将功能提取,用做通用函数,方便其他函数调用
import datetime, time, functools

# def copysrc(src):
#     def _copy(dest):
#         dest.__name__ = src.__name__
#         dest.__doc__ = src.__doc__
#         return dest
#     return _copy
def fla(de,f,fla):#将下面一条语句做成函数提取出来,用做通用函数
    return "{} too slow".format(f.__name__) if de > fla else "{} OK ,is fast".format(f.__name__)

def test(flag):
    def loog(fn):
        @functools.wraps(fn) # 等效于 wrapper = copysrc(fn)(wrapper)
        def wrapper(*args,**kwargs):
            """My name is wrapper"""
            print("{} program start".format(fn.__name__))
            print("args = {},kwargs = {}".format(args,kwargs))
            start = datetime.datetime.now()
            cc = fn(*args, **kwargs)
            print(cc)
            delta = (datetime.datetime.now()-start).total_seconds()
            print("{} program end it took {} seconds".format(fn.__name__, delta))
            fla(delta, fn, flag)
            return cc
        return wrapper
    return loog

@test(2)  # add = loog(add)
def add(x, y, z=2):
    """I am a function ..."""
    time.sleep(1)
    return x + y + z

add(5, 8, z=15)
print("function name is {},function doc is {}".format(add.__name__, add.__doc__))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值