zoukankan      html  css  js  c++  java
  • Python札记 -- 装饰器补充

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

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

     1 #!/usr/bin/env python
     2 
     3 def deco(func):
     4     def wrapper():
     5         print "Wrap start"
     6         func()
     7         print "Wrap end
    "
     8     return wrapper
     9 
    10 @deco
    11 def foo():
    12     """Docstring for foo"""
    13     print "In foo():"
    14 
    15 foo()
    16 print foo.__name__
    17 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。示例代码分别如下:

     1 #!/usr/bin/env python
     2 from functools import update_wrapper
     3 
     4 def deco(func):
     5     def wrapper():
     6         print "Wrap start"
     7         func()
     8         print "Wrap end
    "
     9     return update_wrapper(wrapper,func) #调用update_wrapper方法
    10 
    11 @deco
    12 def foo():
    13     """Docstring for foo"""
    14     print "In foo():"
    15 
    16 foo()
    17 print foo.__name__
    18 print foo.__doc__
     1 #!/usr/bin/env python
     2 from functools import wraps
     3 
     4 def deco(func):
     5     @wraps(func) #使用装饰器来实现
     6     def wrapper():
     7         print "Wrap start"
     8         func()
     9         print "Wrap end
    "
    10     return wrapper
    11 
    12 @deco
    13 def foo():
    14     """Docstring for foo"""
    15     print "In foo():"
    16 
    17 foo()
    18 print foo.__name__
    19 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
  • 相关阅读:
    poj2631 Roads in the North(求树的直径)
    P3809 【模板】后缀排序
    P3376 【模板】网络最大流dinic算法
    3224: Tyvj 1728 普通平衡树
    034 Android IntentService 的使用
    033 Android 绑定Service并与之通信
    032 Android Service
    031 Android 异步任务(AsyncTask)
    030 Android 线程+Handler的使用
    029 Android WebView的使用(用来显示网页)
  • 原文地址:https://www.cnblogs.com/PandaBamboo/p/4016260.html
Copyright © 2011-2022 走看看