Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充。

    使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码:

#!/usr/bin/env python

def deco(func):
    def wrapper():
        print "Wrap start"
        func()
        print "Wrap end\n"
    return wrapper

@deco
def foo():
    """Docstring for foo"""
    print "In foo():"

foo()
print foo.__name__
print foo.__doc__

输出如下:

$ python decorator_test.py
Wrap start
In foo():
Wrap end

wrapper
None

可以发现,__name__属性成了wrapper,而__doc__属性则成了None。这对于平常使用多少带来些不便,总不能给每个使用装饰器的函数都重写__name__和__doc__吧。

    Python的functools提供的update_wrapper和wraps可以有效解决这个问题。不过update_wrapper是用方法的形式进行调用,而wraps则是用装饰器来封装了update_wrapper。示例代码分别如下:

decorator_test_with_update_wrapper.py

#!/usr/bin/env python
from functools import update_wrapper

def deco(func):
    def wrapper():
        print "Wrap start"
        func()
        print "Wrap end\n"
    return update_wrapper(wrapper,func) #调用update_wrapper方法

@deco
def foo():
    """Docstring for foo"""
    print "In foo():"

foo()
print foo.__name__
print foo.__doc__

 

decorator_test_with_wraps.py

#!/usr/bin/env python
from functools import wraps

def deco(func):
    @wraps(func) #使用装饰器来实现
    def wrapper():
        print "Wrap start"
        func()
        print "Wrap end\n"
    return wrapper

@deco
def foo():
    """Docstring for foo"""
    print "In foo():"

foo()
print foo.__name__
print foo.__doc__


现在被deco装饰过的foo方法,可以保留之前的__name__和__doc__属性了。

$ python decorator_test_with_update_wrapper.py
Wrap start
In foo():
Wrap end

foo
Docstring for foo

$ python decorator_test_with_wraps.py
Wrap start
In foo():
Wrap end

foo
Docstring for foo

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值