• python基础--闭包函数和装饰器


    首先我们应该知道一件事:函数的定义域跟定义位置有关系,而跟调用位置没有关系。
    闭包函数:
    定义:内层函数对外层函数而非全局变量的引用,就叫做闭包函数
    闭包会一直存在在内存中,不会因为函数执行结束而被释放
    先看个例子:
    def outer():
        num = 1
        def inner():
            nonlocal num
            num += 1
            print(num)
        return inner
    a = outer() # 此时a为一个函数
    a() # 2
    a() # 3
    a() # 4
    num会一直存在,不会因为外层函数结束而释放。
    这就是闭包函数,可以在任何地方调用
    闭包的意义
    意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,
    这使得无论在何处调用,优先使用自己外层包裹的作用域

    装饰器:闭包函数的一种应用场景
    装饰器原则:1,不修改对象的源代码,2,不修改对象的调用方式,
    目标:在遵循1,2的前提下,为被装饰对象添加上新的功能

    假如我们有这样一个需求,测试一个函数所用的时间
    import time
    def function():
        time.sleep(1)
        print('函数执行')
    start_time = time.time()
    function()
    end_time = time.time()
    print("函数的执行时间%s" %(end_time  - start_time))
    # 但此时多了几行代码,再次修改
    def function():
        time.sleep(1)
        print('函数执行')
    def timeer():
        start_time = time.time()
        function()
        end_time = time.time()
        print("函数的执行时间%s" % (end_time - start_time))
    timeer()
    # 我们要想也计算其他函数的时间怎么办?
    def function1():
        time.sleep(1)
        print('函数执行')
    def timeer(function):
        start_time = time.time()
        function()
        end_time = time.time()
        print("函数的执行时间%s" % (end_time - start_time))
    timeer(function1)
    # 又有了新的要求,我们想要在不改变原函数的调用方式来修改
    # 可以用闭包来实现
    def function2():
        time.sleep(1)
        print('函数执行')
    def timeer(function):
        def inner():
            start_time = time.time()
            function()
            end_time = time.time()
            print("函数的执行时间%s" % (end_time - start_time))
        return inner
    function2 = timeer(function2)
    function2() #这样就可以在不修改函数调用方式的情况下增加功能
    # python有一个语法糖的功能,例子如下
    def timeer(function):
        def inner():
            start_time = time.time()
            function()
            end_time = time.time()
            print("函数的执行时间%s" % (end_time - start_time))
        return inner
    
    @timeer
    # 相当于:function2 = timeer(function2)
    def function2():
        time.sleep(1)
        print('函数执行')
    function2()
    上述就是装饰器的基本方式
    新的问题又来了,我们写的函数有参数怎么办呢?
    我们直接给inner加上参数就好了啊
    注意,此时参数应该怎么加,应该保证同时适用于有参数和无参数的函数
    因为我们不知道函数有几个参数,所以应该用不定长参数
    def timeer(function):
        def inner(*args,**kwargs):
            # 这样函数没有参数也可以用
            start_time = time.time()
            function(*args,**kwargs)
            end_time = time.time()
            print("函数的执行时间%s" % (end_time - start_time))
        return inner
    @timeer
    def function2():
        time.sleep(1)
        print('函数执行')
    @timeer
    def add_num(num1,num2):
        print(num1 + num2)
    function2()
    add_num(3,5)
    不知道大家发现没有,我们还有一个问题没有解决,
    对了,那就是函数的返回值的问题,我们怎么给有返回值的函数加装饰器呢?
    我们从前面可以知道,我们加了装饰器,是会执行装饰器内部的inner函数
    那么我们给inner函数加上返回值就好了啊,看代码:
    def timeer(function):
        def inner(*args,**kwargs):
            # 这样函数没有参数也可以用
            start_time = time.time()
            res = function(*args,**kwargs)
            # 此处用一个变量来接受函数的返回值。
            end_time = time.time()
            print("函数的执行时间%s" % (end_time - start_time))
            # 函数的最后应该有返回值,而且这个返回值必须是function函数执行后的返回值,
            # 那么我们就知道该怎么写代码了,我们用一个变量来接受函数function执行后的返回值就好了啊
            return res
            # 在此处返回
        return inner
    @timeer
    def max_num(num1,num2):
        if num1 > num2:
            return num1
        else:
            return num2
    print(max_num(3,5))
    def outer(function):
        def inner(*args,**kwargs):
            # 函数执行前你想要做的
            res = function()
            # 函数执行后你想要做的
            return res
        return inner
    那么到此处我们就已经掌握了装饰器的内容,上边是一个框架
  • 相关阅读:
    改变传统电视对客厅文化的影响
    移动终端三分天下 何与争峰
    全球移动IM应用的迅猛发展前景
    电子医疗的发展和实现
    poj 1523(无向图求割点)
    poj 3255(次短路)
    poj 2125
    poj 3204
    图的连通度问题的求法(转)
    poj 3308
  • 原文地址:https://www.cnblogs.com/cong12586/p/11356880.html
Copyright © 2020-2023  润新知