zoukankan      html  css  js  c++  java
  • python闭包和装饰器

    一、闭包

    闭包从形式上来说是在外部函数中定义内部函数,并且内部函数引用了外部函数的变量,此变量叫做自由变量

    或者说是将组成函数的语句和这些语句的执行环境打包在一起。

    闭包满足的条件:

    • 必须有一个内嵌函数
    • 内嵌函数必须使用外部函数的变量
    • 外部函数的返回值必须是内嵌函数
    def closure():
        value = []
        def fun(tmp):
            value.append(tmp)
            return value
        return fun
    
    cc = closure() 
    cc(0) #[0] 等同于closure(fun(0))
    cc(1) #[0,1]
    cc(2) #[0,1,2]

    外部函数closure中有变量value和内部函数fun,并且内部函数fun引用了自由变量value,当执行cc = closure()时,就产生了一个闭包fun,该闭包持有只有变量value,当函数closure生命周期结束后,value依然存在,因为它被闭包引用了。

    二、装饰器

    装饰器其实就是闭包的应用,只不过其传递的是函数。

    def add_time(fun):
        def wrapper():
            print('time: 12:00')
            return fun()
        return wrapper
    
    def add_format(fun):
        def wrapper():
            print('
    ')
            return fun()
        return wrapper
    
    @add_format  #等同于demo = add_format(add_time(demo))
    @add_time  #等同于 demo = add_time(demo)
    def demo():
        return 'hello world!'

    另外,装饰器会将demo函数的元信息丢失,例如__name__等等。

    例如demo函数的__name__会由'demo'变成了'wrapper',这时需要用到functools库,在wrapper函数前加上@functools.wraps(fun)

    import functools
    
    def add_time(fun):
        @functools.wraps(fun)
        def wrapper():
            print('time: 12:00')
            return fun()
        return wrapper
    
    def add_format(fun):
        @functools.wraps(fun)
        def wrapper():
            print('
    ')
            return fun()
        return wrapper
    
    @add_format  #等同于demo = add_format(add_time(demo))
    @add_time  #等同于 demo = add_time(demo)
    def demo():
        return 'hello world!'

    例如给任意函数加上打印时间的功能的装饰器:

    def metric(fn):
        start=time.time()
        @functools.wraps(fn)
        def wrapper(*args,**kw):
           end=time.time()
           print('%s executed in %s ms' % (fn.__name__,start-end))
           return fn(*args,**kw)
        return wrapper
  • 相关阅读:
    cf D. Vessels
    cf C. Hamburgers
    zoj 3758 Singles' Day
    zoj 3777 Problem Arrangement
    zoj 3778 Talented Chef
    hdu 5087 Revenge of LIS II
    zoj 3785 What day is that day?
    zoj 3787 Access System
    判断给定图是否存在合法拓扑排序
    树-堆结构练习——合并果子之哈夫曼树
  • 原文地址:https://www.cnblogs.com/LMIx/p/13126617.html
Copyright © 2011-2022 走看看