Python装饰器

来源:互联网 发布:python 数据清洗 框架 编辑:程序博客网 时间:2024/06/01 07:45

装饰器背后的主要动机源自Python面向对象编程。

装饰器是在函数调用之上的修饰。这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用。

装饰器的语法是以@开头,接着是装饰器函数的名字和可选参数。紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数。如:

@decorator(dec_opt_args)

def func2Bdecorator(func_opt_args):

...

...

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

1、装饰器可以如函数调用一样“叠加”,如:

@deco2

@deco1

def func(arg1, arg2, ...): pass

这和创建一个组合函数是等价的。

def func (arg1, arg2, ...): pass

func = deco2(deco1(func))

 

2手动装饰

# 装饰器是一个函数,而其参数为另外一个函数

def my_shiny_new_decorator(a_function_to_decorate) :

 

    # 在内部定义了另外一个函数:一个封装器。

    # 这个函数将原始函数进行封装,所以你可以在它之前或者之后执行一些代码

    def the_wrapper_around_the_original_function() :

 

        # 放一些你希望在真正函数执行前的一些代码

        print "Before the function runs"

 

        # 执行原始函数

        a_function_to_decorate()

 

        # 放一些你希望在原始函数执行后的一些代码

        print "After the function runs"

 

    #在此刻,"a_function_to_decrorate"还没有被执行,我们返回了创建的封装函数

    #封装器包含了函数以及其前后执行的代码,其已经准备完毕

    return the_wrapper_around_the_original_function

 

# 现在想象下,你创建了一个你永远也不远再次接触的函数

def a_stand_alone_function() :

    print "I am a stand alone function, don't you dare modify me"

 

a_stand_alone_function()

#输出: I am a stand alone function, don't you dare modify me

 

# 好了,你可以封装它实现行为的扩展。可以简单的把它丢给装饰器

# 装饰器将动态地把它和你要的代码封装起来,并且返回一个新的可用的函数。

a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)

a_stand_alone_function_decorated()

#输出 :

#Before the function runs

#I am a stand alone function, don't you dare modify me

#After the function runs

现在你也许要求当每次调用a_stand_alone_function时,实际调用却是a_stand_alone_function_decorated。实现也很简单,可以用my_shiny_new_decorator来给a_stand_alone_function重新赋值。

a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)

a_stand_alone_function()

#输出 :

#Before the function runs

#I am a stand alone function, don't you dare modify me

#After the function runs

 

# And guess what, that's EXACTLY what decorators do !

3装饰器揭秘

前面的例子,我们可以使用装饰器的语法:

@my_shiny_new_decorator

def another_stand_alone_function() :

    print "Leave me alone"

 

another_stand_alone_function()

#输出 :

#Before the function runs

#Leave me alone

#After the function runs

当然你也可以累积装饰:

def bread(func) :

    def wrapper() :

        print "</''''''\>"

        func()

        print "<\______/>"

    return wrapper

 

def ingredients(func) :

    def wrapper() :

        print "#tomatoes#"

        func()

        print "~salad~"

    return wrapper

 

def sandwich(food="--ham--") :

    print food

 

sandwich()

#输出 : --ham--

sandwich = bread(ingredients(sandwich))

sandwich()

#outputs :

#</''''''\>

# #tomatoes#

# --ham--

# ~salad~

#<\______/>

使用python装饰器语法:

@bread

@ingredients

def sandwich(food="--ham--") :

    print food

 

sandwich()

#输出 :

#</''''''\>

# #tomatoes#

# --ham--

# ~salad~

#<\______/>

装饰器的顺序很重要,需要注意:

@ingredients

@bread

def strange_sandwich(food="--ham--") :

    print food

 

strange_sandwich()

#输出 :

##tomatoes#

#</''''''\>

# --ham--

#<\______/>

# ~salad~

最后回答前面提到的问题:

# 装饰器makebold用于转换为粗体

def makebold(fn):

    # 结果返回该函数

    def wrapper():

        # 插入一些执行前后的代码

        return "<b>" + fn() + "</b>"

    return wrapper

 

# 装饰器makeitalic用于转换为斜体

def makeitalic(fn):

    # 结果返回该函数

    def wrapper():

        # 插入一些执行前后的代码

        return "<i>" + fn() + "</i>"

    return wrapper

 

@makebold

@makeitalic

def say():

    return "hello"

 

print say()

#输出: <b><i>hello</i></b>

参考

理解Python装饰器

http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html

Python核心编程(第二版)

0 0