• 装饰器


    关于装饰器我们先来了解了解什么是闭包

    0X01

    闭包概念

    closure:内部函数中对enclosing作用域的变量进行引用

    0X02

    看段小Demo

    def func(val):def in_func():
            print (val)
        in_func()
        return in_func
    
    f = func(89)
    f()

    我们首先可以看到在func函数中定义了一个函数in_func,那么调用func函数返回in_func函数。

    从C语言角度讲就是返回了一个函数指针,可是我们看看运行结果

    89
    89

    f()函数的返回结果是89

    func函数调用完成从C语言来角度来说调用栈清除,为什么f()函数还能89呢?

    0X03

    首先我们应该了解的是在Python中与C不同的是Python函数是一种对象

    那么看看val与函数f()的地址

    def func(val):
        print ('%x'%id(val))
        def in_func():
            print (val)
        in_func()
        return in_func
    
    f = func(89)
    f()
    print (f.__closure__)

    运行结果如下

    2ff8598
    89
    89
    (<cell at 0x03025650: int object at 0x02FF8598>,)

    我们发现地址都是0X02FF8598! 

    那么闭包实际就是内置函数把引用的变量放入了自己函数属性中进行返回

    0X04


    既然值可以作为函数属性与函数一起返回,那么函数也可以作为另函数属性返回

    def dec(func):
        def in_dec(*arg):
            print 'In dec'
            if len(arg) == 0:
                return 0
            for val in arg:
                if not isinstance(val, int):
                    return 0
            return func(*arg)
        return in_dec
    
    
    def my_sum(*arg):
        return sum(arg)
    
    
    my_sum = dec(my_sum)
    
    print my_sum(1,2,3,4,5,6)

    如上所示,其实装饰器也就是闭包的一种。

    综上所述
    1.装饰器用来装饰函数
    2.返回一个函数对象
    3.被装饰函数标识符指向返回的函数对象

    0X05

    无参数装饰器

    def dec(func):
        def in_dec(*arg):
            print 'In dec'
            if len(arg) == 0:
                return 0
            for val in arg:
                if not isinstance(val, int):
                    return 0
            return func(*arg)
        return in_dec
    
    
    @dec #my_sum = dec(my_sum)
    def my_sum(*arg):
        return sum(arg)
    
    print my_sum(1,2,3,4,5,6)

    对照上个闭包来看@dec的作用就是 执行了my_sum = dec

    0X06

    有参数装饰器

    有参数装饰器相对于无参数装饰器来说就相当于多了一层嵌套

    def log(prefix):
        def log_decorator(f):
            def wrapper(*args, **kw):
                print '[%s] %s()...' % (prefix, f.__name__)
                return f(*args, **kw)
            return wrapper
        return log_decorator
    
    @log('DEBUG')
    def test():
        pass
    print test()

    我们把@log('DEBUG')进行展开

    my_func = log('DEBUG')(my_func)

    上面的语句看上去还是比较绕,再展开一下:

    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)

    上面的语句又相当于:

    log_decorator = log('DEBUG')
    @log_decorator
    def my_func():
        pass

    本质上就是多返回了一层装饰器而已

     

  • 相关阅读:
    MySQL 的连接时长控制--interactive_timeout和wait_timeout
    查看MySQL 连接信息--连接空闲时间及正在执行的SQL
    mysql timestamp为0值时,python读取后的对象为None
    MySQL基础普及《MySQL管理之道:性能调优、高可用与监控》
    读《大秦帝国》第三部
    golang mysql 如何设置最大连接数和最大空闲连接数
    如何查看MySQL connection id连接id
    JAVA配置环境变量
    PB常见功能实现代码
    PB中数据窗口自动换行
  • 原文地址:https://www.cnblogs.com/zibility/p/5607464.html
Copyright © 2020-2023  润新知