• python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)


    21.闭包

    1. 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量)
    2. 闭包的作用:1.保证数据的安全性(纯洁度)。2.装饰器使用
    3. .__closure__判断是否是闭包
    def func():
        a = 1 
        def foo():
            print(a)
        return foo
    ret = func()
    ret()
    #例子
    def func():
        avg_lst = []
        def foo(pirce):
            avg_lst.append(pirce)
            avg = sum(avg_lst) / len(avg_lst)
            return avg
        return foo
    ret = func()
    print(ret(1500))
    print(ret(1600))
    print(ret.__closure__)#结果:(<cell at 0x000002095400B558: list object at 0x00000209540A5B48>,)证明是闭包
    print(func.__closure__)#结果:None,不是闭包
    
    print(ret.__code__.co_freevars)#获取的是自由变量
    print(ret.__code__.co_varnames)#获取的是局部变量
    

    22.装饰器一(入门)

    1.一个装饰器装饰多个函数

    开放封闭原则:扩展是开放的(增加新功能),源码是封闭的(修改已经实现的功能)

    作用:在不改变源代码及调用方式的基础下额外增加新功能。

    装饰器:用来装饰的工具

    2.版一:
    import time
    start_time = time.time
    def func():
        time.sleep(2)#睡眠s模拟网络延时
        print("我要飞")
    func()   
    print(time.time - start_time)
    #改变了源代码
    
    3.版二:
    def times(f):
        start_time = time.time()
        f()
    	print(time.time() - start_time)
    def foo():
        time.sleep(3)
        print("我飞的比你高")
    #times(foo)#改变了调用方式
    s = foo
    foo = times
    foo(s)#不改变调用方式
    
    
    4.版三:(low版装饰器)
    def times(f):
        def inner():
            start_time = time.time()
            f()
    	    print(time.time() - start_time)
    	return inner
    def foo():
        time.sleep(3)
        print("我飞的比你高")
    foo = times(foo)
    foo()
    
    5.版四:
    def wrapper(f):
        def inner(a):
            start_time = time.time()
            f(a)
           	print(time.time() - start_time)
        return inner#切记不加括号
    
    def func(a):
        print(f"{a}你不行")
    func = wrapper(func)
    func("alex")
    #传输多个数据,用*args,**kwargs
    
    
    6.版五(标准版装饰器):

    @wrapper#语法糖:必须放在要装饰的函数的正上方

    def wrapper(f):#f是要被装饰的函数名
        def inner(*args,**kwargs):
            "被装饰前"
            start_time = time.time()
            ret = f(*args,**kwargs)
           	print(time.time() - start_time)
            "被装饰后"
            return ret
        return inner#切记不加括号
    @wrapper#语法糖 -->func = wrapper(func)
    def func(*args,**kwargs):
        print(f"{a}你不行")
        return "我可以返回了"
    #func = wrapper(func)#有语法糖不用多次赋值
    func("alex")
    

    23.装饰器二(进阶)

    1.有参装饰器:

    ​ 有参装饰器:在基础装饰器的基础上再套一层函数

    #有参装饰器实现登陆验证
    msg = """
    QQ
    微信
    抖音
    请输入您要登录的的app:
    """
    chose = input(msg).upper()
    dict_flag = {'username':None,'flag':False}
    def auth(a):
        def wrapper(f):
            def inner(*args,**kwargs):
                if dic_flag['flag']:
                    fun(*args,**kwargs)
        		else:
                    if argv =="QQ":
                        print("欢迎登陆QQ")
                        user = intput("user:")
                        pwd = input("passwd:")
                        if user == "alex" and pwd == "alex123":
                            dict_flag["flag"] = True
                            dict_flag["username"] = user
                            foo(*args,**kwargs)
                            
                        else:
                            print("用户名或密码错误!")
            return inner
        return wrapper
    @auth(chose)
    """
    语法糖拆分:
    wrapper = auth(chose)
    foo = wrapper(foo)
    """
    def foo():
    	print("这是被装饰的函数")
    foo()
    

    2.多个装饰器装饰一个函数:

    ​ 当被装饰的函数正上方有多个装饰器,先执行里被装饰函数最近的装饰器(小技巧:进入装饰器,从上往下,走到最后一个装饰器,执行被装饰的函数,退出装饰器从下往上)

    def wrapper1(f):
        def inner1(*args,**kwargs):
            print("这是第一个装饰器开始")
            f(*args,**kwargs)
            print("这是第一个装饰器结束")
            return 
        return inner1
    
    def wrapper2(f):
        def inner2(*args,**kwargs):
            print("这是第二个装饰器开始")
            f(*args,**kwargs)
            print("这是第二个装饰器结束")
            return 
        return inner2
    
    @wrapper1
    @wrapper2
    """
    两个语法糖等价于:
    foo = wrapper2(foo)#foo == inner2
    foo = wrapper1(foo)#foo = wrapper(inner2),foo == inner1
    foo()#-->inner1()
    """
    def foo():
        print("这是被装饰的函数")
    foo()
    '''
    结果:
    这是第一个装饰器开始
    这是第二个装饰器开始
    这是被装饰的函数
    这是第二个装饰器结束
    这是第一个装饰器结束
    '''
    

  • 相关阅读:
    使用 EasyBCD 安装Ubuntu 14.04 Error 15: file not found错误的解决方法
    浅谈程序猿的职业规划,看你如何决定自己的未来吧。
    [转载]DOS循环:bat/批处理for命令详解 (史上虽详尽的总结和说明~~)
    bat 批处理 字符串 截取
    window上使用GIT的个人经验(入门级)
    Android 访问 wcf
    解决 MyEclipse 10 中 JSp页面 “return false” 报错问题
    微信公共平台(码农在努力)
    Spring Cloud 中使用 Zipkin 追踪服务
    Spring Cloud Config 分布式配置中心
  • 原文地址:https://www.cnblogs.com/Onlywang/p/11241567.html
Copyright © 2020-2023  润新知