美文网首页python杂记
装饰器简介与使用

装饰器简介与使用

作者: 摸不去的尘 | 来源:发表于2016-10-29 19:12 被阅读32次

装饰,《辞源》解释为“装者,藏也,饰者,物既成加以文采也。”指的是对器物表面添加纹饰、色彩以达到美化的目的。

python里的装饰器本质是一个函数,一个可以接受函数作为参数,返回值是函数的函数。它可以不改变一个函数代码的情况为这个函数提供额外功能,从而起到美化和重用代码作用。主要在用户验证、,插入日志、事物处理、缓存场景中使用。

例如,现在有两个函数代码如下:

def foo():
    ''' This is foo function '''
    print 'I am foo'
def bar():
    ''' This is bar function '''
    print 'I am bar'

现在需求有变更,需要给foo、bar两个函数添加日志来记录函数名字,防止以后出现问题便于定位问题:

def foo():
    ''' This is foo function '''
    logging.warn('foo is running' )
    print 'I am foo'

def bar():
    ''' This is bar function '''
    logging.warn('bar is running')
    print 'I am bar'

看可以上面那段代码出现了两次loggin.warn调用,每次需要改动原有函数代码,但是装饰器代码更简洁:

装饰器
def log(func):
    def wrapper(*args, **kwargs):
        logging.warn('%s is running % func.__name__)
        return func(*args, **kwargs)
    return wrapper

@log
def foo():
    ''' This is foo function '''
    print 'I am foo'

@log
def bar():
    ''' This is bar function '''
    print 'I am bar'

@是python一种语法糖,可以在被装饰函数上面用@加装饰器名,来使用装饰器。但是装饰器装饰函数,会创建一个动态函数来替换原来的,然而,新函数缺少会很多原函数的属性,如docstring和名字。幸好,万能的python提供functions包wraps函数来解决这个问题,修改后代码如下:

def log(func):
    @functions.wraps(func)     # 多了这行代码
    def wrapper(*args, **kwargs):
        logging.warn('%s is running % func.__name__)
        return func(*args, **kwargs)
    return wrapper

@log
def foo():
    ''' This is foo function '''
    print 'I am foo'

@log
def bar():
    ''' This is bar function '''
    print 'I am bar'

另外,如果传入被修饰函数带有位置参数和关键字参数,可以使用inspect.getcallargs提供更加智能处理方法,不用判断某个参数是位置参数还是关键字参数。只需要在inspect.callcargs返回参数名字-值为键值对的字典中查找即可,代码如下:

def log(func):
    @functions.wraps(func)
    def wrapper(*args,**kwargs):
        func_args = inspect.getcallargs(func, *args, **kwargs)   # 使用inspect内省功能获取参数
        if func_args.get('username') != 'admin':
           raise Exception('This user can not modify data')
        return func(*args, **kwargs)
    return wrapper

相关文章

  • 装饰器简介与使用

    装饰,《辞源》解释为“装者,藏也,饰者,物既成加以文采也。”指的是对器物表面添加纹饰、色彩以达到美化的目的。 py...

  • Python | 装饰器

    使用场景 装饰器 ' @ ' 使用 带参数装饰器 装饰器类

  • 13. Python之装饰器

    1 什么是装饰器 2 为何要用装饰器 3 如何使用装饰器 4 语法糖 5 叠加多个装饰器,加载顺序与运行顺序 6 ...

  • Python进阶-装饰器

    这篇文章要解决的问题: # 装饰器是什么? # 装饰器的种类? # 为什么使用装饰器? # 怎么使用装饰器? # ...

  • Python中的装饰器

    Python中的装饰器 不带参数的装饰器 带参数的装饰器 类装饰器 functools.wraps 使用装饰器极大...

  • Python基础28-面向对象(系统内置方法8-装饰器)

    8 装饰器 1 装饰器(函数式实现) 2 通过类方式,实现装饰器 通常装饰器使用 使用@check 方式实际上就是...

  • [译] Python装饰器Part II:装饰器参数

    这是Python装饰器讲解的第二部分,上一篇:Python装饰器Part I:装饰器简介 回顾:不带参数的装饰器 ...

  • python 单例的实现

    使用装饰器 使用

  • Python进阶 装饰器

    一切皆对象 原始的装饰器 使用@的装饰器 蓝本规范 带参数的装饰器 装饰器类

  • python 装饰器的使用--逐步添加中

    装饰器是什么:装饰器的通用:带参数的装饰器的使用:装饰器的使用范围:入门之前,先提几个问题,然后依次回答这些问题。...

网友评论

    本文标题:装饰器简介与使用

    本文链接:https://www.haomeiwen.com/subject/xvsyuttx.html