python的装饰器

学习廖雪峰老师的教程做的笔记
当我们不想改变原有函数的定义,又想对函数功能进行增强,可以使用Decorator修饰器进行动态增强。
举例:

def date():
    print('2018-08-01')

我们想对date()函数进行增强:在运行的时候加上日志
func.name:函数的name属性,可以拿到函数的名字

def log(func):      #因为log是一个Decorator,所以可以接收一个函数作为参数,并返回一个函数
    def demo(*args, **kw):   #传入参数是*args, **kw,可以接收任意参数,所以下面的func(*args, **kw)可以调用
        print('当前调用方法 %s()返回结果:' % func.__name__)
        return func(*args, **kw)
    return demo

@log #使用python的@语法,把decorator置于函数的定义处
def date():
    print('2018-08-01')
date()

执行结果:

D:\front-end\python>python decorator.py
当前调用 date()函数返回结果:
2018-08-01

如果log()函数需要传入参数,即decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数

def log(text):
    def decorator(func):
        def demo(*args, **kw):
            print('log()参数: %s 当前调用 %s()函数:' % (text, func.__name__))
            return func(*args, **kw)
        return demo
    return decorator

@log('execute')
def date():
    print('2018-08-01')

date()

执行结果:

D:\front-end\python>python decorator.py
log()参数: execute 当前调用 date()函数:
2018-08-01

这样会出现一个问题:

>>> date.__name__  #__name__属性获取的是demo,而不是date
'demo'

因为返回的那个demo()函数名字就是’demo’,所以,需要把原始函数的name等属性复制到demo()函数中,否则,有些依赖函数签名的代码执行就会出错,Python内置的functools.wraps可以把原始函数的name等属性复制到新函数中,只要引入functools模块之后,在新函数头上加上@functools.wraps(func)即可,举例:

>>> import functools
>>> def log(text):
...     def decorator(func):
...             @functools.wraps(func)
...             def demo(*args, **kw):
...                     print('log()参数: %s 当前调用 %s()函数:' % (text, func.__name__))
...                     return func(*args, **kw)
...             return demo
...     return decorator
...
>>> @log('execute')
... def date():
...     print('2018-08-01')
...
>>> date()
log()参数: execute 当前调用 date()函数:
2018-08-01
>>> date.__name__
'date'
>>>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值