码迷,mamicode.com
首页 > 编程语言 > 详细

python中的装饰器

时间:2015-03-30 13:31:30      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

装饰器的本质:

当你在用某个@decorator来修饰某个函数func时,如下所示:

@decorator
def func():
    pass

其解释器会解释成下面这样的语句:

func=decorator(func)

本质是把一个函数当作参数传递到另一个函数中,然后再调用。

def hello(fn):
    def wrapper():
        print "hello,%s" %fn.__name__
        fn()
        print "goodbye,%s" %fn.__name__
    return wrapper

@hello
def foo():
    print "I am foo"

>>>foo()
"hello,foo"
"I am foo"
"goodbye,foo"

hello(foo)返回了wrapper()函数,所以foo其实变成了wrapper的一个变量,而后面的foo()执行其实变成了wrapper()

多个装饰器:

@decorator_one
@decorator_two
def func():
    pass

相当于func=decorator_one(decorator_two(func))

带参数的装饰器:

@decorator(arg1,arg2)
def func():
    pass

相当于func=decorator(arg1,arg2)(func).这意味着decorator(arg1,arg2)这个函数需要返回一个“真正的装饰器”。

def mydecorator(arg1,arg2):
    def _mydecorator1(func):
        def _mydecorator2(*args,**kw):
            res=func(*args,**kw)
            return res
        return _mydecorator2
    return _mydecorator1

上面的函数返回的_mydecorator1才是真正的装饰器。因此,当装饰器需要参数时,必须使用第二集封装。因为装饰器在模块第一次被读取时由解释程序装入,所以它们的使用必须受限于总体上可以应用的封装器。

带参数及多个装饰器:

def makeHtmlTag(tag,*args,**kwds):
    def real_decorator(fn):
        css_class="class=‘{0}‘".format(kwds["css_class"]) if "css_class" in kwds else ""
        def wrapped(*args,**kwds):
            return "<"+tag+css_class+">"+fn(*args,**kwds)+"</"+tag+">"
        return warpped(*args,**kwds)
    return real_decorator

@makeHtmlTag(tag=‘i‘,css_class=‘italic_css‘)
@makeHtmlTag(tag=‘b‘,css_class=‘bold_css‘)
def hello():
    return "hello world"
>>>hello()
<i class=‘italic_css‘><b class=‘bold_css‘>hello world</b></i>

class式装饰器:

class mydecorator(object):
    def __init__(self,fn):
        print "inside mydecorator--init"
        self.fn=fn
    def __call__(self):
        self.fn()
        print "inside mydecorator--call"

@mydecorator
def myfunc():
    print "inside myfunc"
>>>myfunc
"inside mydecorator--init"
"inside myfunc"
"inside mydecorator--call"

重写makeHtmlTag代码:


python中的装饰器

标签:

原文地址:http://my.oschina.net/935572630/blog/393489

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!