• 闭包函数及装饰器


    闭包函数

    闭包函数的定义:

      闭:定义在函数内部的函数

      包:内部函数引用了外部函数作用域的名字

    给函数体传值的两种方式:

    1.传参

    def index1(username):
        print(username)

    2.闭包

    def outter(x,y):  #在函数内传参,在res1中调用,相当于x=1,y=40
        # x = 1
        # y = 40
        def my_max():
            if x > y:
                return x
            return y
        return my_max
    res1 = outter(1,40)  # res就是my_max函数的内存地址
    print(res1())   #这里打印的还是1和40,想结束不让他打印1和40的话只能结束程序或者再传其他参数
    print(res1())
    print(res1())
    res2 = outter(90,200)
    print(res2())
    print(res2())
    import requests  
    
    def outter(url):  #给函数传参,在my_jd中定义实参传给形参
        # url = 'https://www.jd.com'  #固定传参
        def my_get():
            response = requests.get(url)
            if response.status_code == 200:  
                print(len(response.text))
        return my_get
    my_jd = outter('https://www.jd.com')  #my_jd接收的是my_get的内存地址
    my_jd()
    my_jd()
    my_baidu = outter('https://www.baidu.com')
    my_baidu()
    my_baidu()
    my_baidu()
    my_baidu()
    my_baidu()

    装饰器

    装饰器:

      器:就是一个工具

      装饰:给被装饰对象添加新的功能

    为什么要用装饰器?

      开放封闭原则:

        开放:对扩展开放

        封闭:对修改开放

      装饰器(可调用对象)必须遵循的两个原则:

        1.不改变被装饰对象的源代码

        2.不改变被装饰对象(可调用对象)调用方式

    首先写一个time模块的示例

    import time
    def index():
        time.sleep(3)   # 让CPU睡3秒
        print('开业啦')
    
    start = time.time()  # 程序运行开始时的时间
    index()
    end = time.time()    #程序结束时的时间
    print('index run time:%s'%(end-start))  # 计算程序从开始到结束所用的时间

    如何写一个计算时间的装饰器呢?不同的函数名都可以应用

    import time
    def index():
        time.sleep(3)
        print('开业啦')
    
    def outter(func):  # func = 最原始的index函数的内存地址
        def get_time():
            start = time.time()
            func()  # func = index函数的内存地址() 直接调用
            end = time.time()
            print('index run time:%s'%(end-start))
        return get_time
    index = outter(index)  # outter(最原始的index函数内存地址)
    # index指向get_time函数的内存地址
    index()

    如何写一个同时支持有参和无参的装饰器

    import time
    def index():   #无参函数
        time.sleep(3)
        print('开业啦')
        return 'index'
    res1 = index()
    
    def login(name): #有参函数
        time.sleep(1)
        print('%s is s'%name)
        return 'login'
    res = login('zhangsan')
    
    def outter(func):  # func = 最原始的login函数的内存地址
        def get_time(*args, **kwargs):  # 写*args和**kwargs可以同时支持有参和无参,可以接收任意数量的参数
            start = time.time()
            res = func(*args, **kwargs)  # 最原始的login函数的内存地址() 直接调用  func('egon')
            end = time.time()
            print('func run time:%s'%(end-start))
            return res
        return get_time
    login = outter(login)

    语法糖

    def outter(func):  # func = 最原始的index函数的内存地址
        def get_time(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)  # 最原始的index函数的内存地址() 直接调用  
            end = time.time()
            print('func run time:%s'%(end-start))
            return res
        return get_time
    
    
    @outter   # 语法糖,等同于index = outter(index),outter会直接把离他最近的一个函数名当做自己的参数传入
    def index():
        time.sleep(3)
        print('开业啦')
        return 'index'

    装饰器模板

    def outter(func):
        def inner(*args, **kwargs)
            print('执行被装饰函数之前,可以做的操作')
            res = func(*args, **kwargs)
            print('执行被装饰函数之后,可以做的操作')
            return res
        return inner

    认证装饰器

      执行函数index之前必须先输入用户名和密码 正确之后才能执行index,否则提示用户输入错误 结束程序。

    import time
    user_dic = {'is_login':None}  #定义一个字典存放用户登录的状态
    
    def login_auth(func):
        # func = index
        def inner(*args,**kwargs):
            if user_dic['is_login']:  # 如果用户已经在登录状态
                res = func(*args, **kwargs)  
                return res  #直接将参数返回
            else:
                username = input('please input your username>>>:').strip()
                password = input('please input your password>>>:').strip()
                if username == 'wu' and password == '123':
                    user_dic['is_login'] = True
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('username or password error')
        return inner

    装饰器补充 @wraps

    def outter(func):
        @wraps(func)    
        def inner(*args, **kwargs)
            print('执行被装饰函数之前,可以做的操作')
            res = func(*args, **kwargs)
            print('执行被装饰函数之后,可以做的操作')
            return res
        return inner
    
    # 用户查看被装饰函数的函数名的时候查看到的就是被装饰函数本身
    # 用户查看被装饰函数的注释的时候查看到的就是被装饰函数的注释
  • 相关阅读:
    来看看面试必问的HashMap,一次彻底帮你搞定HashMap源码
    深入浅出!springboot从入门到精通,实战开发全套教程!
    讲一讲Java的字符串常量池,看完你的思路就清晰了
    面向对象的这些核心技术,你掌握后包你面试无忧
    他凭借这70份PDF,3170页文件,成功斩获了含BATJ所有的offer
    springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!
    这行代码告诉你!为什么你地下城与勇士(DNF)的装备强化老是失败?
    精益求精!Spring Boot 知识点全面回顾,带你重新细读源码!
    太妙了!Spring boot 整合 Mybatis Druid,还能配置监控?
    putchar(".:-=+*#%@"[(int)(d * 5.0f)])
  • 原文地址:https://www.cnblogs.com/chengzige/p/11173251.html
Copyright © 2020-2023  润新知