zoukankan      html  css  js  c++  java
  • python——函数装饰器

    闭包

    如果在一个内部函数(函数里的函数)里,对在外部作用域(但不是在全局作用域,可以理解为外层函数)的变量进行引用,那么内部函数就被认为是闭包。

    例如:

    def outer():
        x=10             # 这里x即为外部作用域变量
        def inner():
            print(x)
        return inner     # inner函数被称为一个闭包
    

    装饰器

    写python代码一定要遵循开放封闭原则。即,可扩展功能,对源代码修改是封闭的。装饰是为函数和类指定管理代码的一种方式。装饰器本身的形式是处理其他的可调用对象的可调用的对象(如函数)。它们主要只是一种语法糖。

    装饰器有两个原则:不改变原来函数的调用方法;不改变原来函数的源代码。

    注:根据我自己的实验,递归函数尽量不要使用装饰器,否则会函数嵌套函数,出现各种bug;比如斐波那契函数:
    
    import time
    # 为函数增加 统计执行时长
    def show_time(func):
        def inner(n):
            start_time=time.time()
            func(n)
            end_time=time.time()
            print("takes %d s"%(end_time-start_time))
            return func(n)
        return inner
    
    #**********************
    @show_time 
    def fibo(n):
        if 1 < n <= 3:
            return 1
        elif n==1:
    	    return 0
        elif n<=0:
            return "please input an int greater than 0."
        return fibo(n-1)+fibo(n-2)
    
    print(fibo(31))
    #*********************** 星号这部分就会有问题
    
    
    @show_time
    def fib(n):
        a = 0
        b = 1
        if n >= 3:
            for i in range(n+1)[3:]:
                a,b=b,a+b
                result = b
            return result
        elif n == 1:
    	    return a
        elif n ==2:
    	    return b
        else:
    	    return "please input an int greater than 0."
    
    print(fib(80000))            # for循环的就没有问题
    

    装饰器支持嵌套:

    @A
    @B
    def C():
        print("in the c")
    

    python装饰器有两种形式:

    • 函数装饰器在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法或随后对它们的调用。
    • 类装饰器在类定义的时候进行名称重绑定,提供一个逻辑层来管理类,或管理随后调用它们所创建的示例。

    装饰器举例:

    import time
    
    def show_time(func):
        def inner():
            start_time=time.time()
            func()
            end_time=time.time()
            print("takes %d s"%(end_time-start_time))
        return inner
    
    @show_time             # 等于  foo=show_time(foo)
    def foo():
        print("in the foo.")
        print("foo...")
        time.sleep(3)
    
    @show_time             # 等于  bar=show_time(bar)
    def bar():
        print("in the bar.")
        print("bar...")
        time.sleep(2)
    

    装饰器参数:给装饰器加参数。还以上面例子来说,给bar函数加上日志记录,foo函数不加。

    import time
    
    def logger(flag='false'):
        def show_time(func):
            def inner():
                start_time=time.time()
                func()
                end_time=time.time()
                print("takes %d s"%(end_time-start_time))
                if flag == 'true':
                    print("write logs...")
            return inner
        return show_time
    
    #@show_time             # 等于  foo=show_time(foo)
    @logger()
    def foo():
        print("in the foo.")
        print("foo...")
        time.sleep(3)
    
    #@show_time             # 等于  bar=show_time(bar)
    @logger('true')
    def bar():
        print("in the bar.")
        print("bar...")
        time.sleep(2)
    如需转载,请注明出处,否则本人会追究法律责任!
  • 相关阅读:
    852. Peak Index in a Mountain Array
    841. Keys and Rooms
    832. Flipping an Image
    821. Shortest Distance to a Character
    824. Goat Latin
    如何生成git的公钥和私钥
    学习笔记
    加快JavaScript加载和执行效率
    PO BO VO DTO POJO DAO概念及其作用
    jvm 垃圾回收区的形象说明
  • 原文地址:https://www.cnblogs.com/hacker001/p/10091419.html
Copyright © 2011-2022 走看看