• 闭包装饰器与递归


    闭包

    定义

    1. 闭包是嵌套在函数中的函数。
    2. 闭包必须是内层函数对外层函数的变量(非全局变量)的引用。
    3.默认参数就是闭包原理
    4.函数拥有自由变量
    

    如何判断判断闭包

    如果此函数拥有自由变量,那么就可以侧面证明其是否是闭包函数了
    利用 函数名.__code__.co_freevars 查看函数的自由变量
    

    闭包的作用

    保存局部信息不被销毁,保证数据的安全性。
    

    装饰器

    1.遵循开放封闭原则:
        开放:对代码的拓展开放的, 更新地图,加新枪,等等。
        封闭:对源码的修改是封闭的。
    2.在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。
    装饰器就是一个函数。
    

    标准版的装饰器

    def wrapper(f):
        f = zz  # 第2步
        def inner(*args, **kwargs):  # 第5步
            ret = f(*args,**kwargs)#第7步
            return ret
        return inner  # 第3步
    @wrapper  #语法糖做了这件事 zz=weapper(zz) 第一步
    def zz(): # 第4步 此时zz 为 inner
        pass
    

    带参数的装饰器

    def wrapper_out(n,*args,sex="男")
        def wrapper(f):
            def inner(*args,**kwargs):
                ret = f(*args,**kwargs)  # 这边执行的是func1()
                return ret
            return inner
        return wrapper
    
    def func1():
        print("in func1")
    func = wrapper_out(1)  # wrapper函数名
    ly = fun(func1)  # inner = wrapper(func1)
    ly()  # inner()
    def wrapper_out(n):
        def wrapper(f):
            def inner(*args,**kwargs):
                if n == "qq":
                    username = input("请输入用户名:").strip()
                    password = input("请输入密码:").strip()
                    with open("qq",encoding="tuf-8") as f1:
                        for line in f1:
                            user,pwd = line.strip().split("|")
                            if username == user and password == pwd:
                                print("登陆成功")
                                ret = f(*args,**kwargs)
                                return ret
                            return False
                
                elif n == "yiktok":
                    username = input("请输入用户名:").strip()
                    password = input("请输入密码:").strip()
                    with open("qq",encoding="tuf-8") as f1:
                        for line in f1:
                            user,pwd = line.strip().split("|")
                            if username == user and password == pwd:
                                print("登陆成功")
                                ret = f(*args,**kwargs)
                                return ret
                            return False
     
    
    def wrapper_out(n):
        def wrapper(f):
            def inner(*args,**kwargs):                     
                username = input("请输入用户名:").strip()
                password = input("请输入密码:").strip()
                with open(n,encoding="tuf-8") as f1:
                        for line in f1:
                            user,pwd = line.strip().split("|")
                            if username == user and password == pwd:
                                print("登陆成功")
                                ret = f(*args,**kwargs)
                                return ret
                            return False
            return inner
        return wrapper
    
    @ wrapper_out("qq")
    def qq():
        print("成功访问qq")
    qq()
    # 看到带参数的装饰器分两步执行:
    
    @ wrapper_out("腾讯")
        # 1.执行wrapper_out("腾讯"),把相应的参数传给n,并且得到返回值wrapper函数名
        # 2.将@与wrapper结合,得到我们之前熟悉的标准版装饰器,按照装饰器的执行流程执行
        
    @ wrapper_out("qq")
    def qq():
        print("成功访问qq")
        
    @ wrapper_out("tiktok")
    def tiktok():
        print("成功访问抖音")
        
    qq()
    tiktok()
    # 开发思路:增强耦合性
    

    多个装饰器装饰一个函数

     def wrapper1(func1):  # func1 = f原函数
        def inner1():
            print('wrapper1 ,before func')  # 2
            func1()
            print('wrapper1 ,after func')  # 4
        return inner1
    
    def wrapper2(func2):  # func2 == inner1
        def inner2():
            print('wrapper2 ,before func')  # 1
            func2()  # inner1
            print('wrapper2 ,after func')  # 5
        return inner2
    
    
    @wrapper2  # f = wrapper2(f) 里面的f == inner1  外面的f == inner2
    @wrapper1  # f = wrapper1(f) 里面的f == func1   外面的f == inner1  先看下面
    def f():
        print('in f')  # 3
    
    f()  # inner2()  看外层f
    

    递归

    1.官网规定:默认递归的最大深度1000次。
    2.递归效率很低 总是要开辟空间, 递归比起循环来说更占用内存
    3.递归就是自己调自己
    4.修改递归的最大深度
        # import sys
        # sys.setrecursionlimit(1000000000)
    

    递归的剖析

    # 递归函数是怎么停下来的?递归3次结束整个函数
    # 一个递归函数要想结束,必须在函数内写一个return,并且return的条件必须是一个可达到的条件
    # --注意---并不是函数中有return,return的结果就一定能够在调用函数的外层接收到  谁调用最后一个函数返回给谁
    # 加上return tet
    # def func(count):
    #     count += 1
    #     print(count)
    #     if count == 5 : return 5#这个5其实是返回给下面的func()
    #     ret = func(count)#要想把这个5返回给最外层 所以逐层returt
    #     return ret
    # 精简版
    def func(count):
        count += 1#这里是代码思路
        if count == 5 :
            return 5#这个5其实是返回给下面的func()
        return  func(count)#精简了上面的过程
    

    递归的列子

    1.计算阶乘 100! = 100*99*98*97*96....*1
    def fin(n):
        if n ==1 :
            return n
        else:
            return n*fin(n-1)
    ret = fin(7)
    print(ret)
    l2 = [1, 3, 5, ['太白','元宝', 34, [33, 55, [11,33]]], [77, 88],66]
    
    # 递归
    # def func(alist):
    #     for i in alist:
    #         if type(i) == list:
    #             func(i)  # func(['太白','元宝',34])
    #         else:
    #             print(i)
    # func(l2)
    
    
    2.三级菜单 可能是n级
    3.os模块:查看一个文件夹下的所有文件,这个文件夹下面还有文件夹,不能用walk
    4.os模块:计算一个文件夹下所有文件的大小.这个文件夹下面还有文件夹,不能用 walk
    5.计算斐波那契数列找第100个数
    6.计算阶乘 100! = 100*99*98*97*96....*1
    
  • 相关阅读:
    优化MySchool数据库(存储过程)
    优化MySchool数据库(事务、视图、索引)
    优化MySchool数据库(四)
    优化MySchool数据库(三)
    SQLAchemy
    python操作mysql
    python队列
    零碎知识
    super深究
    Python操作RabbitMQ
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12386291.html
Copyright © 2020-2023  润新知