@decorator可以动态实现函数功能的增加,但是,经过@decorator“改造”后的函数,和原函数相比,除了功能多一点外,有没有其它不同的地方?

在没有decorator的情况下,打印函数名:

def f1(x):
pass
print f1.__name__

输出:

 f1

有decorator的情况下,再打印函数名:

def log(f):
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper
@log
def f2(x):
pass
print f2.__name__

输出:

wrapper

可见,由于decorator返回的新函数函数名已经不是'f2',而是@log内部定义的'wrapper'。这对于那些依赖函数名的代码就会失效。decorator还改变了函数的__doc__等其它属性。如果要让调用者看不出一个函数经过了@decorator的“改造”,就需要把原函数的一些属性复制到新函数中:

def log(f):
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
wrapper.__name__ = f.__name__
wrapper.__doc__ = f.__doc__
return wrapper

这样写decorator很不方便,因为我们也很难把原函数的所有必要属性都一个一个复制到新函数上,所以Python内置的functools可以用来自动化完成这个“复制”的任务:

import functools
def log(f):
@functools.wraps(f)
def wrapper(*args, **kw):
print 'call...'
return f(*args, **kw)
return wrapper

最后需要指出,由于我们把原函数签名改成了(*args, **kw),因此,无法获得原函数的原始参数信息。即便我们采用固定参数来装饰只有一个参数的函数:

def log(f):
@functools.wraps(f)
def wrapper(x):
print 'call...'
return f(x)
return wrapper

也可能改变原函数的参数名,因为新函数的参数名始终是 'x',原函数定义的参数名不一定叫 'x'。

python中完善decorator的更多相关文章

  1. python 中的decorator

    python 中decorator的作用就是一个包装的作用,所谓包装指在执行真正的函数之前或者之后,我们可以有一些额外的发挥余地. decorator形式如下 def dec(arg1): print ...

  2. python中的decorator的作用

    1.概念 装饰器(decorator)就是:定义了一个函数,想在运行时动态增加功能,又不想改动函数本身的代码.可以起到复用代码的功能,避免每个函数重复性编写代码,简言之就是拓展原来函数功能的一种函数. ...

  3. 谈谈Python中的decorator装饰器,如何更优雅的重用代码

    众所周知,Python本身有很多优雅的语法,让你能用一行代码写出其他语言很多行代码才能做的事情,比如: 最常用的迭代(eg: for i in range(1,10)), 列表生成式(eg: [ x* ...

  4. 浅析python中的装饰器decorator

    最近学习python,其中decorator比较难理解,遂写一篇来总结供后续查阅. 定义一个函数,想在运行时动态的改变函数的功能,又不想改变函数本身的代码,可以使用高阶函数(可以使用函数作为参数) 装 ...

  5. python中decorator

    先讲一下python中的@符号 看下面代码 @f @f2 def fun(args, args2, args3, args4, ……): pass 上面代码相当于 def fun(args, args ...

  6. decorator在Python中的作用

    decorator(装饰器)在python中作用,可以起到代码复用,也可以起到AOP(面向横切面)的作用. 另外很重要的一点应该就是function在python的世界中是作为一等公民存在的. 在py ...

  7. python中decorator的用法及原理(一)

    0. 概念 什么叫装饰器,其实也可以叫做包装器.即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来. Python中的装饰器分为两类:函数装饰器和类 ...

  8. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...

  9. [转] Python中的装饰器(decorator)

    想理解Python的decorator首先要知道在Python中函数也是一个对象,所以你可以 将函数复制给变量 将函数当做参数 返回一个函数 函数在Python中和变量的用法一样也是一等公民,也就是高 ...

随机推荐

  1. HashMap? ConcurrentHashMap?

    前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...

  2. 搭建RocketMQ踩的坑-内存不足

    环境是vmvare+ubuntu 1.http://rocketmq.apache.org/docs/quick-start/ 按照官网来启动mqnamesrv和mqbroker报错 错误如下 The ...

  3. 第一百七十九节,jQuery-UI,知问前端--按钮 UI-图标

    jQuery-UI,知问前端--按钮 UI 学习要点: 1.使用 button 按钮 2.修改 button 样式 3.button()方法的属性 4.button('action', param) ...

  4. Spring MVC错误处理

    以下示例显示如何在使用Spring Web MVC框架的表单中使用错误处理和验证器.首先使用Eclipse IDE来创建一个WEB工程,实现一个输入用户信息提交验证提示的功能.并按照以下步骤使用Spr ...

  5. Uva1025 A Spy in the Metro

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; ]; ] ...

  6. Linux之(Git)服务之windows配置

    设置你自己的昵称与email设置本地机器默认commit的昵称与Email. 请使用有意义的名字与email. git config --global user.name "syavingc ...

  7. ipod锁定后的恢复

    1.断开 USB 线缆与设备的连接,但保持线缆的另一端与电脑的 USB 端口相连. 2.关闭设备:按住“睡眠/唤醒”按钮数秒,直到出现红色滑块,然后滑动该滑块.等待设备关闭. 3.按住主屏幕按钮,同时 ...

  8. jQuery方法find()与children()区别

    一.find() 1.1 说明 find()方法返回被选元素的后代元素,一路向下直到最后一个后代. 1.2 示例 <div> <p> <span>1</spa ...

  9. leetCode 64.Minimum Path Sum (最短路) 解题思路和方法

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  10. Python 学习之旅

    流程图 第一章  Python简介 第二章  Python基础 第三章  流程控制 第四章  字符编码 第五章  文件处理 第六章  函数 第七章 模块与包 第八章 面向对象 第九章 异常处理 第十章 ...