本随笔是对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。示例代码分别如下:

 #!/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__
 #!/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

Python札记 -- 装饰器补充的更多相关文章

  1. python day6 装饰器补充,正则表达式

    目录 python day 6 1. 装饰器decorator 2. 正则表达式re 2.1 正则表达式概述 2.2 re模块常用方法 python day 6 2019/10/09 学习资料来自老男 ...

  2. python之装饰器补充与递归函数与二分查找

    目录 多层装饰器 有参装饰器 递归函数 基本演示 斐波那契数列 总结 小拓展 算法之二分法 简介 举例 总结 多层装饰器 我们已经知道了语法糖的作用是将装饰对象自动装饰到装饰器中,一个语法糖的应用我们 ...

  3. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  4. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  5. Python的装饰器实例用法小结

    这篇文章主要介绍了Python装饰器用法,结合实例形式总结分析了Python常用装饰器的概念.功能.使用方法及相关注意事项 一.装饰器是什么 python的装饰器本质上是一个Python函数,它可以让 ...

  6. 第五章 Python之装饰器

    函数对象 函数是第一类对象:即函数可以当作数据传递 #可以被引用,可以被当作参数传递,返回值可以是函数,可以当作容器类型的元素 #引用 def func(x,y): print(x,y) f=func ...

  7. 我终于弄懂了Python的装饰器(四)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 四 ...

  8. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  9. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

随机推荐

  1. 第二章 jQuery数组和字符串

    章节内容: 1.利用数组在列表中显示名字 (1)利用数组显示名字列表--join()方法 (2)从数组中获取名字并追加到有序列表--each()方法 (3)利用HTML元素创建数组和计算数组长度--g ...

  2. IosPush推送通知的实现

    1. Apple推送通知的机制 上图可以分为三个阶段: 第一阶段:应用程序把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中, ...

  3. tomcat 性能优化

    tomcat 性能优化tomcat默认参数是为开发环境制定,而非适合生产环境,尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈. tomcat内存优化linux修改TOMCAT_HOME/bin/ ...

  4. C++实现简单的单链表

    下面实现的是一个简单的单链表 功能不多,学习使用 #pragma once #include <iostream> using namespace std; class ListEx { ...

  5. js跨域访问

    什么是跨域 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首 ...

  6. 如何去掉div滚动条

    1.去掉横向滚动条 style="overflow-x:hidden" 2.去掉纵向滚动条 style="overflow-y:hidden" 3.同时去掉横向 ...

  7. ActionBar

    Android actionBar 修改背景色 本来是想着自定义标题栏,发现老是出错.貌似4.0以上版本都不能自定义标题栏(我到现在都搞不清标题栏和actionBar的区别到底是什么!).原来需要自定 ...

  8. 小JAVA大世界之程序建模跳蚤实验

    package com.chigoe;//房子类class House { private int m;// 保存行数 private int n;// 保存列数 private int[][] a; ...

  9. java JFrame窗体真正关闭

    程序: package JFrame.bao; import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent; impor ...

  10. ubuntu 14 中tomcat的开机启动设置

    开机自启动,将要执行的语句写入/etc/rc.local. #!/bin/sh -e # # rc.local # # This script is executed at the end of ea ...