• 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)
    如需转载,请注明出处,否则本人会追究法律责任!
  • 相关阅读:
    C# -- HttpWebRequest 和 HttpWebResponse 的使用
    C# -- Lambda 表达式的使用
    ASP.NET -- WebForm -- HttpRequest类的方法和属性
    ASP.NET -- WebForm -- HttpResponse 类的方法和属性
    C# -- 索引器、枚举类型
    C#设计模式之七桥接模式(Bridge Pattern)【结构型】
    C#设计模式之六适配器模式(Adapter Pattern)【结构型】
    C#设计模式之五原型模式(Prototype Pattern)【创建型】
    C#设计模式之四建造者模式(Builder Pattern)【创建型】
    C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】
  • 原文地址:https://www.cnblogs.com/hacker001/p/10091419.html
Copyright © 2020-2023  润新知