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

    闭包

    闭包的定义

    1.闭:定义在函数内部的函数
    2.包:内部函数引用了外部函数作用域的名字

    函数的参数传达

    1.直接传参
    
    def index1(username):
        print(username)
    2.闭包来实现函数内参数传达
    
    def outter(x,y):
        # x = 1
        # y = 40
        def my_max():
            if x > y:
                return x+y
            return  y
        return my_max
    res1 = outter(1, 40)
    print(res1)
    
    res2 = outter(90,200)
    print(res2())

    闭包实例

    import requests
    
    url1 = 'https://www.baidu.com'
    def my_ger(url):
        response = requests.get(url)
        if response.status_code == 200:
            print(len(response.text))
    
    my_ger(url1)
    my_ger('https://www.baidu.com')

    装饰器

    装饰器定义

    器指的是工具,而程序中的函数就是具备某一功能的工具,所以装饰器指的是为被装饰器对象添加额外功能。因此定义装饰器就是定义一个函数,只不过该函数的功能是用来为其他函数添加额外的功能。
    
    需要注意的是:
    
    装饰器本身其实是可以任意可调用的对象
    被装饰的对象也可以是任意可调用的对象

    装饰器的实现必须遵循两大原则:

    不修改被装饰对象的源代码
    不修改被装饰对象的调用方式

    单函数的实现装饰器的效果(超low版本)

     实现函数名为参数的闭包 (simple版本)

     

     实现解决调用函数参数的不固定问题(正常版本)

    在被装饰函数正上方,并且是单独一行写上@装饰器名  装饰糖

    实现作用 实际为 装饰器函数的返回值(一般都是内层函数的函数名) = 装饰器函数(被装饰函数函数名)

     

     装饰器模板

     多层装饰器(包括传参案例)

    '''多层装饰器'''
    import time
    
    user_dic = {'is_logth':None}
    
    def outter(func):
        def get_time(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            end = time.time()
            print(f'func run rime:{(end-start)}')
            return res
        return get_time
    
    def login_auth2(data_source, x, t):
        # data_source = 'file'
        def login_auth(func):
            # func = index
            def inner(*args, **kwargs):
                if user_dic['is_logth']:
                    res = func(*args, **kwargs)
                    return res
                else:
                    if data_source == 'file':
                        username = input('plesse input your username>>>:').strip()
                        password = input('plesse input your password>>>:').strip()
                        if username == 'jinpan' and password == '123':
                            user_dic['is_logth'] = True
                            print(func)
                            res = func(*args, **kwargs)
                            return res
                        else:
                            print('username or password error')
                    elif data_source == 'Mysql':
                        print('from Mysql')
                    elif data_source == 'ldap':
                        print('ldap')
                    else:
                        print("暂无该数据来源")
            return inner
        return login_auth
    
    @login_auth2('file',1,2)
    @outter
    def index():
        time.sleep(1)
        print('index')
        return 'index'
    res = index()
    print(res)

     装饰器修复器 -- wraps的用法

    使用help() __name__ 方法对被装饰器对象时候恢复原有的名字和注释

    '''
    装饰器修复器---wraps用法
    '''
    from functools import wraps
    def outter(func):
        @wraps(func)
        def inner(*args, **kwargs):
            '''
            我是inner函数
            :param args:
            :param kwargs:
            :return:
            '''
            print('执行被装饰函数之前 你可以执行的操作')
            res = func(*args, **kwargs)
            print('执行被装饰函数之后 你可以执行的操作')
            return res
        return inner
    
    @outter
    def index():
        """
        这是index函数
        :return:
        """
        pass
    
    print(index)
    print(help(index))
    print(index.__name__)
    index()
    '''
    用户查看被装饰函数的函数名的时候查看到的就是被装饰函数本身
    用户查看被装饰函数的函数名的时候查看到的就是被装饰函数注释
    '''

     装饰器的函数的加载和执行顺序

    加载顺序自下到上

    执行顺序自上到下

    '''多层装饰器的练习案例'''
    def outter1(func1):
        print('加载了outter1')
        def wrapper1(*args,**kwargs):
            print('执行了wrapper1')
            res1 = func1(*args,**kwargs)
            return res1
        return wrapper1
    
    def outter2(func2):
        print('加载了outter2')
        def wrapper2(*args,**kwargs):
            print('执行了wrapper2')
            res2 = func2(*args,**kwargs)
            return res2
        return wrapper2
    
    def outter3(func3):
        print('加载了outter3')
        def wrapper3(*args,**kwargs):
            print('执行了wrapper3')
            res3 = func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    @outter1
    @outter2
    @outter3
    def index():
        print('from index')
    
    """
    加载了outter3
    加载了outter2
    加载了outter1
    
    执行了wrapper1
    执行了wrapper2
    执行了wrapper3
    from index
    """
    
    index()
  • 相关阅读:
    App集成支付宝
    关于Objective-c和Java下DES加密保持一致的方式
    Android开发规范
    android 屏幕适配问题
    Android AES加密算法及其实现
    linux文件系统调用(1)---mount
    Java(Android)解析KML文件
    【Akka】在并发程序中使用Future
    函数指针问题,求解答
    android旋转动画的两种实现方式
  • 原文地址:https://www.cnblogs.com/jinpan/p/11173917.html
Copyright © 2011-2022 走看看