Python之装饰器(二)

                                                    Python之装饰器(二)

           之前总结了装饰器的简单原理,本次主要总结有参函数的装饰。

一、装饰有参函数:add(a, b)

       装饰器通过返回包装对象实现间接调用,插入额外功能。如下例,装饰有参函数add(a, b),在函数运行前sleep()一段时间。实际上,add = func = wapper, 所以func()和wapper()需要加上参数,而为了使程序更加有扩展性,可添加可变参数*agrs和 **kwargs。

def delay(func):
    def wrapper(*args, **kwargs):    # 1
        time.sleep(1)
        ret = func(*args, **kwargs)  # 2
        print("delay 1 second before call %s" % func.__name__)
        return ret                   # 原函数返回值
    return wrapper


@delay
def add(a, b):
    return a + b

二、带参装饰器:@decorator(parameter = value)

@delay_p(parameter='A') #
def add1(a, b):
    return a + b

       获取被装饰函数的信息,从而可实现不同函数采取不一样的装饰效果。而要将parameter参数传递到装饰器中,再加一层函数来接受参数。类似嵌套函数的概念,执行内函数,先执行外函数。以上带参的装饰器可写成如下调用形式:

delay_p = delay_p(parameter)
add1 = delay_p(add1)

装饰器加一层函数接收参数,其他的与无参装饰器类似。

def delay_p(parameter):
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):        # 1
            if parameter == 'A':
                time.sleep(5)
                ret = func(*args, **kwargs)
                print("delay 5 second before call %s" % func.__name__)
            else:
                time.sleep(4)
                ret = func(*args, **kwargs)
                print("delay 4 second before call %s" % func.__name__)
            return ret
        return wrapper
    return outer_wrapper


@delay_p(parameter='A')
def add1(a, b):
    return a + b


@delay_p(parameter='B')
def add2(a, b):
    return a + b
各函数调用结果:

 

三、@wraps

       装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数,函数的属性已被装饰器改变。

print(add.__name__, add.__doc__)     # wrapper None
print(add1.__name__, add1.__doc__)   # wrapper decor

     Python的functools包中functools.wraps可消除这样的影响,将原函数对象的指定属性复制给包装函数对象。使其保留原有函数的名称和docstring。如下 # 1处加入 @wraps(func), 运行结果:add1 Docstring add1

from functools import wraps     # 

def delay_p(parameter):
    def outer_wrapper(func):
        @wraps(func)            # 1
        def wrapper(*args, **kwargs):
            """decor"""
            if parameter == 'A':
                time.sleep(5)
                ret = func(*args, **kwargs)
                print("delay 5 second before call %s" % func.__name__)
            else:
                time.sleep(4)
                ret = func(*args, **kwargs)
                print("delay 4 second before call %s" % func.__name__)
            return ret
        return wrapper
    return outer_wrapper


@delay_p(parameter='A')
def add1(a, b):
    """Docstring add1"""
    return a + b

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值