python装饰器

二层装饰器函数

def log(func):
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper
@log
def now():
    print '2013-12-25'

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

三层装饰器函数

由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。

wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print '%s %s():' % (text, func.__name__)
            return func(*args, **kw)
        return wrapper
    return decorator
@log('execute')
def now():
    print '2013-12-25'

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

       now = log('execute')(now)

我们来剖析上面的语句,首先执行log('execute'),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数。

以上两种decorator的定义都没有问题,但还差最后一步。因为我们讲了函数也是对象,它有name等属性,但你去看经过decorator装饰之后的函数,它们的name已经从原来的'now'变成了'wrapper':

# This is our decorator
def simple_decorator(f):
    # This is the new function we're going to return
    # This function will be used in place of our original definition
    def wrapper():
        print "Entering Function"
        f()
        print "Exited Function"
 
    return wrapper
 
@simple_decorator 
def hello():
    print "Hello World"
 
hello()

那么我们怎样才能给我们的装饰器传参数?要实现这个我们只需创建一个“decorator_factory”函数,我们调用这个函数,返回适用于我们函数的装饰器。现在看看如果实现它。

def decorator_factory(enter_message, exit_message):
    # We're going to return this decorator
    def simple_decorator(f):
        def wrapper():
            print enter_message
            f()
            print exit_message
 
        return wrapper
 
    return simple_decorator
 
@decorator_factory("Start", "End")
def hello():
    print "Hello World"
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,...
    chen_000阅读 1,442评论 0赞 3
  • 装饰器简述 要理解装饰器需要知道Python高阶函数和python闭包,Python高阶函数可以接受函数作为参数,...
    XYZeroing阅读 396评论 0赞 1
  • 装饰器 定义Python装饰器 装饰器是一种设计模式, 可以使用OOP中的继承和组合实现, 而Python还直接从...
    sonack阅读 1,484评论 0赞 1
  • 二 说说我和飘是怎么认识的吧。 我们刚上高三的时候认识的,但其实飘是暗恋了我一年的,在高二的时候我换了发型,很...
    苌玖阅读 266评论 0赞 1
  • 人的一辈子匆匆几十年,年少的我们往往心高气傲,总想活在自己肆无忌惮的世界,但现实的世界,自身的情况,有时候并不...
    启盛阅读 796评论 1赞 1

友情链接更多精彩内容