装饰器

作者: 四阿哥萌萌哒 | 来源:发表于2019-07-18 21:39 被阅读0次

    闭包

    # 定义一个函数
    def test(number):
    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数, number_in is %d" % number_in)
        return number+number_in
    # 其实这里返回的就是闭包的结果
    return test_in 
    # 给test函数赋值,这个20就是给参数number  
    ret = test(20)
    # 注意这里的100其实给参数number_in
    print(ret(100))
    #注 意这里的200其实给参数number_in
    print(ret(200))
    

    运行结果

    in test_in 函数, number_in is 100 120
    in test_in 函数, number_in is 200  22
    

    闭包的作用:

    1.函数名只是函数代码空间的引用,当函数名赋值给一个对象的时候 就是引用传递

    2.闭包就是一个嵌套定义的函数,在外层运行时才开始内层函数的定义,然后将内部函数的引用传递函数外的对象

    3.内部函数和使用的外部函数提供的变量构成的整体称为闭包

    初识装饰器

      def decorate(func):
         def inner(): 
            return "<i>"+func()+"</i>"
        return inner 
      @decorate
      def func():
        return "你好"
        print(func())
    

    运行结果

    <i>你好</i>
    

    以看出装饰器就是在闭包的基础上做了一些修改

    装饰器传参

    from time import ctime, sleep
     
    def timefun(func):
        def wrapped_func(*args, **kwargs):
            print("%s called at %s"%(func.__name__, ctime()))
            func(*args, **kwargs)
        return wrapped_func
     
    @timefun
    def foo(a, b, c):
        print(a+b+c)
     
    foo(1,2,3)
    sleep(1)
    foo(4,5,6)
    

    运行结果

    foo called at Thu Aug 23 21:32:50 2018
    6
    foo called at Thu Aug 23 21:32:51 2018
    15
    

    装饰器工厂(flask定义一个路由的方式)

    from time import ctime, sleep
     
    def timefun_arg(pre="hello"):
        def timefun(func):
            def wrapped_func():
                print("%s called at %s %s" % (func.__name__, ctime(), pre))
                return func()
            return wrapped_func
        return timefun
     
     
    @timefun_arg("php")
    def foo():
        print("I am foo")
     
    @timefun_arg("python")
    def too():
        print("I am too")
     
    foo()
    sleep(2)
    foo()
     
    too()
    sleep(2)
    too()
    

    运行结果

    foo called at Thu Aug 23 21:40:34 2018 php
    I am foo
    foo called at Thu Aug 23 21:40:36 2018 php
    I am foo
    too called at Thu Aug 23 21:40:36 2018 python
    I am too
    too called at Thu Aug 23 21:40:38 2018 python
    I am too
    

    小结

    在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。

    例如打印日志,利用装饰器可以轻松实现业务逻辑和控制逻辑的解耦

    日志装饰器:

    class LogPlus:
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args, **kwargs):
            print 'start call {}'.format(self.func.__name__)
            self.func(*args, **kwargs)
            print 'end call {}'.format(self.func.__name__)
    
    @LogPlus
    def hello():
        print '2017-11-06'
    

    输出

    start call hello
    2017-11-06
    end call hello
    

    相关文章

      网友评论

          本文标题:装饰器

          本文链接:https://www.haomeiwen.com/subject/gvirlctx.html