zoukankan      html  css  js  c++  java
  • [python基础]关于装饰器

        在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是这样,真佩服我当时厚着脸皮回答的那些问题...

        OK,先来张图看看装饰器内容:

        

      OK,我们留下一个印象,然后我们看实际的场景来操作.

      我们先看一个方法:

    __author__ = 'bruce'
    
    
    def do_sth():
        print 'some thing has been done'
    
    
    if __name__ == '__main__':
        do_sth()
    

      

    假定一个方法,我们现在提出一个需求,将每个方法追加一个写日志的功能,这样方便我们统计。

    第一次更改:硬代码

    __author__ = 'bruce'
    
    
    def do_sth():
        print 'the function is begin'
        print 'some thing has been done'
        print 'the function is end'
    
    
    if __name__ == '__main__':
        do_sth()

    看样子是符合需求,但是这里一个问题,现在只是针对特定的do_sth()方法了,那如果我们还有do_first_sth(),do_second_sth()......等更多的方法,难道我们每一个都是都去copy然后在去粘贴这些内容吗?

    第二次更改:灵活变动

    __author__ = 'bruce'
    
    
    def do_sth():
        print 'some thing has been done'
    
    
    def log_sth(func):
        print 'the function is begin'
        func()
        print 'the function is end'
    
    if __name__ == '__main__':
        log_sth(do_sth)

    这样,方法被当作参数一样传递给log_sth,这样我们只需要调用log_sth就可以灵活的写日志了,在逻辑上当然没有问题了,假如do_sth()被N处调用,那我们是不是必须得把do_sth()在N处都要更改过来,那假如你的这个函数是给别人使用的,你这样修改直接导致别人无法使用了。

    第三次更改:内置引用

    __author__ = 'bruce'
    
    
    def do_sth():
        print 'some thing has been done'
    
    
    def log_sth(func):
        def wrapper():
            print 'the function is begin'
            func()
            print 'the function is end'
    
        return wrapper
    
    
    if __name__ == '__main__':
        foo = log_sth(do_sth)
        foo()

    这样就内置的实现了一个函数调用另一个函数,我们可以很形象的手中有两张牌然后插入另外一张牌,很像一个横切面,这个就叫叫面向切面编程(AOP),每次调用dosth时,都从上到下顺序的执行了外层函数,从语义上来看do_sth这个方法被log_sth这个词语修饰了,这种行为在python就是装饰器,python有更优雅的方法实现这个操作

    __author__ = 'bruce'
    
    
    def log_sth(func):
        def wrapper():
            print 'the function is begin'
            func()
            print 'the function is end'
    
        return wrapper
    
    
    @log_sth
    def do_sth():
        print 'some thing has been done'
    
    
    if __name__ == '__main__':
        do_sth()

    @log_sth就像是形容词一样,放置在do_sth函数的上方

    有人会说,你这只是针对于没有参数的函数,那如果有参数的函数应该怎么写呢?

    第四次变更:针对有参数的函数的装饰器

    __author__ = 'bruce'
    
    
    def log_sth(func):
        def wrapper(*args, **kwargs):
            print 'the function is begin'
            func(*args, **kwargs)
            print 'the function is end'
    
        return wrapper
    
    
    @log_sth
    def do_sth(sth=None):
        if not sth:
            sth = 'there is nothing'
        print sth
    
    
    if __name__ == '__main__':
        do_sth()

    OK,通过上面一些简单的实例,我们了解到装饰器的一些实际应用,关于更多的例子请参考如下的列表:

    Python的Decorator 杂谈
    Python装饰器学习(九步入门)
    理解Python中的装饰器
     
  • 相关阅读:
    [C#]画图全攻略(饼图与柱状图)(转)
    ZedGraph控件的使用
    android PopupWindow实现从底部弹出或滑出选择菜单或窗口
    那两年炼就的Android内功修养
    android添加edittext后布局就不好用
    第三方应用分享到微信朋友圈功能
    android的微信签名
    Android开源库
    Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
    android 显示特殊符号
  • 原文地址:https://www.cnblogs.com/codefish/p/5013076.html
Copyright © 2011-2022 走看看