Python的修饰器@

修饰器是一个很著名的时机模式,经常用于有切面需求的场景,如插入日志、性能测试、事务处理等。修饰器能够很好地解决这些问题,有了修饰器我们能抽离出大量函数中与函数功能本身无关的雷同代码并继续使用。也就是说,修饰器的作用就是为已经存在的函数对象添加额外的功能。

1.修饰器入门:

1.1.需求的由来:

修饰器的定义很抽象,先来看一个例子:

def foo():
    print "in foo()"
    
foo()

这个函数的功能是打印出一窜字符窜。如果想要测试执行这个函数用了多长时间,我们可以这样做:

import time
def foo():
    start = time.clock()
    print "in foo()"
    end = time.clock()
    print "used:",end-start
    
foo()

这样能够很好的达到目的。但是想测试一个模块的所有函数的执行时间呢,就得把所有函数中都加入如上时间差的计算方法,这样不太现实。

1.2.以不变应万变

为了不改变原来的函数,我们可以定义一个函数timeit,将foo()的引用传递给他,然后在timeit中调用fool并进行计时,这样我们就不用修改foo函数而达到目的了。

import time

def foo():
    print "in foo()"
    
def timeit(func):
    start = time.clock()
    func()
    end = time.clock()
    print "used:",end - start
    
timeit(foo)

这样看上去逻辑没有问题,而且可以正常的工作。但却修改了调用部分的代码,原本是foo()调用,现在却成了timeit(foo),如果foo在很多处都被调用了,就需要在很多处修改代码。

1.3最大限度的少改动

如果不改动调用的代码,也就意味着调用foo()需要产生timeit(foo)的效果。我们可以这样做,把timeit(foo)的返回值付给foo,然后直接调用foo(),就不用修改源代码了。

import time

def foo():
    print "in foo()"
    
def timeit(func):
    def wrapper():
        start = time.clock()
        func()
        end = time.clock()
        print "used:",end - start
    
    return wrapper
    
foo = timeit(foo)
foo()

这样,我们只需在定义foo以后和调用foo之前,加上foo=timeit(foo),就可以达到目的了。这就是修饰器,看起来像foo被timeit修饰了。

2.正规的修饰器

上面的代码,看似没法再精简了,python于是提供了一个特殊的语法来降低字符输入量:

import time

def timeit(func):
    def wrapper():
        start = time.clock()
        func()
        end = time.clock()
        print "used:",end - start
        
    return wrapper
    
@timeit
def foo():
    print "in foo()"
    
foo()

在第12行的@timeit,效果和foo=timeit(foo)一样,而且看上去更有修饰器的感觉。

这就是Python中修饰器的原理

时间: 2024-10-06 07:47:22

Python的修饰器@的相关文章

python函数修饰器(decorator)

python语言本身具有丰富的功能和表达语法,其中修饰器是一个非常有用的功能.在设计模式中,decorator能够在无需直接使用子类的方式来动态地修正一个函数,类或者类的方法的功能.当你希望在不修改函数本身的前提下扩展函数的功能时非常有用. 简单地说,decorator就像一个wrapper一样,在函数执行之前或者之后修改该函数的行为,而无需修改函数本身的代码,这也是修饰器名称的来由. 关于函数 在Python中,函数是first class citizen,函数本身也是对象,这意味着我们可以对

python中用修饰器进行异常日志记录

当脚本中需要进行的的相同的异常操作很多的时候,可以用修饰器来简化代码.比如我需要记录抛出的异常: 在log_exception.py文件中, import functools import logging def create_logger(): logger = logging.getLogger("test_log") logger.setLevel(logging.INFO) fh = logging.FileHandler("test.log") fmt =

python 通用 修饰器

import functools def log(option): def dec(func): def swapper(*arg, **karg): functools.update_wrapper(swapper, func) opt = format(option,"^7") print '['+opt+"] enter",func.__name__ res = func(*arg, **karg) print '['+opt+'] exit',func.__

PYTHON修饰器的函数式编程

转自:http://coolshell.cn/articles/11265.html Python修饰器的函数式编程 Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都很相似--都是想要对一个已有的模块做一些"修饰工作",所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能

Python修饰器

Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都很相似——都是想要对一个已有的模块做一些“修饰工作”,所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去.但是OO的Decorator简直就是一场恶梦,不信你就去看看wikipedia上的词条(Deco

python 修饰器 最好的讲解

Python的修饰器的英文名叫Decorator,修饰器就是对一个已有的模块做一些"修饰工作",比如在现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去. Python 的 Decorator在使用上和Java/C#的Annotation很相似,就是在方法名前面加一个@XXX注解来为这个方法装饰一些东西.但是,Java/C#的Annotation也很让人望而却步,太TMD的复杂了,你要玩它,你需要了解一堆An

谈谈python修饰器

前言 对python的修饰器的理解一直停留在"使用修饰器把函数注册为事件的处理程序"的层次,也是一知半解:这样拖着不是办法,索性今天好好整理一下关于python修饰器的概念及用法. 介绍 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 功能 我们首先从一个简单的例子

python 修饰器

因困扰自己多时,打算整理一下修饰器到底是什么? 参考资料:http://python.jobbole.com/82344/ 修饰器 1. 定义2个函数 2. 基本实现 3. 问题:实现后, 要修改原来代码中的变量名, funcB()改为funcA(funcB) 4. 解决方法:让funcB赋值等于funcA(funcB),用时就是funcB(), 不用修改原来代码, 这个要求需funcA(funcB)返回的是一个函数     a) 所以要返回一个函数,则加一个函数 wrapper(),然后ret

Python的wraps修饰器详解

本文和大家分享的主要是python 中wraps 修饰器相关内容,一起来看看吧,希望对大家 学习python有所帮助. 在了解  wraps  修饰器之前,我们首先要了解  partial  和  update_wrapper  这两个函数,因为在 wraps  的代码中,用到了这两个函数. partial 首先说  partial  函数,在  官方文档  的描述中,这个函数的声明如下:  functools.partial(func, *args, **keywords)  .它的作用就是返