zoukankan      html  css  js  c++  java
  • 装饰器 递归

    装饰器

    开放封闭原则

    • 开放 : 对扩展是开放的 ( 允许代码扩展、添加新功能 )
    • 封闭 : 对 修改 , 源代码 以及 调用方式 是封闭的

    初识装饰器

    定义:

    • 装饰器本身就是一个函数 , 在不改变原被装饰的函数的源代码以及调用方式下,为其添加一个额外的功能。
    import time # (格林尼治时间 , 也叫时间截)  测试执行效率
    
    def fun(): #2.00022554397583
        time.sleep(2)  # 模拟一下网络延迟以及代码的效率
        print("欢迎访问博客园主页")
    
    def index(): #2.001535654067993
        time.sleep(2)  # 模拟一下网络延迟以及代码的效率
        print('欢迎访问博客园首页')
        
    def home(): #3.000067710876465
        time.sleep(3)  # 模拟一下网络延迟以及代码的效率
        print(f'欢迎访问主页')
        
    def timer(func):  # func = index
        def inner():
            start_time = time.time()
            func()
            end_time = time.time()
            print(f'此函数的执行效率为{end_time-start_time}')
        return inner
    
    
    timer(fun)()
    

    带返回值的装饰器

    import time
    def index():
        time.sleep(2)  # 模拟一下网络延迟以及代码的效率
        print('欢迎访问博客园主页')
        return '访问成功'
    
    def timer(func):  # func = index
        def inner():
            start_time = time.time()
            ret = func()  # '访问成功'
            end_time = time.time()
            print(f'此函数的执行效率为{end_time - start_time}')
            return ret  # '访问成功'
    
        return inner
    
    
    index = timer(index)  # inner
    print(index())  # print(inner())
    print(timer(index)())   # '访问成功'
    

    被装饰函数带参数的装饰器

    单一参数的装饰器

    # 单一参数的装饰器
    import time
    def index():
        time.sleep(2)  # 模拟一下网络延迟以及代码的效率
        print('欢迎访问博客园主页')
        return '访问成功'
    
    def home(name):
        time.sleep(3)  # 模拟一下网络延迟以及代码的效率
        print(f'欢迎访问{name}主页')
    
    def timer(func):  # func = home
        def inner(name):
            start_time = time.time()
            func(name)  # home(name) == home('太白')
            end_time = time.time()
            print(f'此函数的执行效率为{end_time-start_time}')
        return inner
    
    # 要想timer装饰home函数怎么做?
    home = timer(home)
    home('太白')  # 注意将返回给 inner(name)返回值 会返回给timer(func)  None
    

    动态参数的装饰器(举例)

    # 动态参数的装饰器
    
    import time
    def index():
        time.sleep(2)  # 延迟两秒执行下面的代码
        print("欢迎访问博客园主页")
        return "访问成功"
    
    def home(name,age):
        time.sleep(3)
         print(f"欢迎访问{age}岁的{name}的博客园主页")
        
    def timer(func):
        def inner(*args,**kwargs):  # 形参位置 *聚合:args = ('太白',18)
            star_time = time.time()
            func(*args,**kwargs)    # 执行位置的*是打散  func('太白',18)
            stop_time = time.time()
            print(f"此函数的执行效率是{stop_time - star_time}")
            return "好靓的发型"
        return inner
    
    
    home = timer(home)
    home("太白",22)
    
    # 在被修饰函数(home)上面加上@装饰器函数名(timer),就等同于那句话 home = timer(home)
    # @timer 相当于 home = timer(home)
    import time
    
    
    def timer(func):
        def inner(*args, **kwargs):  # 形参位置 *聚合:args = ('太白',18)
            star_time = time.time()
            #  func(*args, **kwargs)  # 执行位置的*是打散  func('太白',18)
            ret = func(*args, **kwargs)  # 带返回值的原函数
            stop_time = time.time()
            print(f"此函数的执行效率是{stop_time - star_time}")
            return ret
    
        return inner
    
    
    @timer 
    def home(name, age):
        time.sleep(3)
        print(f"欢迎访问{age}岁的{name}的博客园主页")
        return true
    
    
    home("太白", 23)
    print(home("太白", 23))
    

    标准版装饰器

    代码优化:语法糖 @ / 优化语法

    • 在被修饰函数(home)上面加上@ + 装饰器函数名(timer),就等同于那句话 home = timer(home)

    语法糖@的执行方式

    • @ 会向下读一行 , 将原函数的函数存到内存 传到装饰器 函数的形参 上 并将原函数名() = 装饰器函数名(原函数名)

    标准版的装饰器

    def wrapper(func):  # wrapper 包装
        def inner(*args,**kwargs):
            '''执行被装饰函数之前的操作'''
            ret = func
            '''执行被装饰函数之后的操作'''
            return ret
        return inner
    

    装饰器→简单登录

    # 简单登录验证
    ogin = {"flag":False}
    # flag = False
    def auth(f):
        def inner(*args,**kwargs):
            # global flag   # 在函数最前面先声明 要改变全局变量 flag
            if login["flag"]:
            # if flag:
                ret = f(*args,**kwargs)
                return ret
            user = input("user>>>")
            passwords = input("passwords>>>")
            if user.strip() == "杨泽涛很帅" and passwords.strip() == "确实帅":
                login["flag"] = True
                # flag = True
                ret = f(*args,**kwargs)
                
                return ret
                
        return inner
    
    @auth
    def article():
        print('欢迎访问文章页面')
    
    @auth
    def diary():
        print('欢迎访问日记页面')
    
    @auth
    def comment():
        print('欢迎访问评论页面')
    
    article()
    diary()
    comment()
    

    装饰器→自定义循环原函数

    def wrapper(f):
        def inner(*args,**kwargs):
            for i in range(*args):
                f(*args,**kwargs)
                
         return inner
    
    @wrapper
    def func(n):
        print("没错循环的我")
    
    func(n)
    

    装饰器 → 录入文件时间

    import time
    def wrapper(f):
        def inner(*args,**kwargs):
            start_time = time.localtime()
            ret = time.strftime("%Y-%m-%d %H:%M:%S", start_time) # 当前时间节点 ymdhms → 年月日时分秒
            f()
            ret_1 = f.__name__
            with open ("文件时间录入.excel",mode = "r+",encoding = "utf-8") as file_1:
                file_1.seek(0,2)
                file_1.write(f"
    {ret_1}_{ret}")
                
        return inner
    
    @wrapper
    def func():
        print("快来录入")
        
        
    func()
    
    # start_time = time.localtime()  
    # ret = time.strftime("%Y-%m-%d %H:%M:%S", start_time)
    # 自动生成指定格式的日期串  func_2019-06-24 17:56:36
    

    装饰器 → 限制该函数被调用的频率

    # 请实现一个装饰器,限制该函数被调用的频率,如3秒一次(借助于time模块,time.time())
    import time
    '''
    if 第二次执行的时间 - 第一次执行的时间 > 3: 逆推法
       第一次时间节点: 123443543.546  - 0  肯定 > 3
       第二次进入:time.time() 123443545.546  - 123443543.546 < 3''''
    
    
    def wrapper(f):
        t = 0
        def inner(*args,**kwargs):
            nonlocal t
            if time.time() - t > 3:
                ret = f(*args,**kwargs)
                return ret
                
            
        return inner 
    
    @wrapper
    def func():
        print("666")
        
    func()
    time.sleep(3)
    func()
    

    带参数的装饰器

    • 装饰器里多套了一层函数来判定多项参数的选择结果
    login = False
    def auth(x):
        
        def auth2(func):
            
            def inner(*args,**kwargs):
                global login
                
                if login:
                    ret = func()
                    return ret
                
                if x = "wechat":
                    user = input(">>>用户名:").strip()
                    passwords = input(">>>密码:").strip()
                    if user == "杨泽涛" and passwords == "123":
                        login = True
                        ret = func()
                        return ret
                    
                if x = "QQ":
                    user = input(">>>用户名:").strip()
                    passwords = input(">>>密码:").strip()
                    if user == "杨泽涛" and passwords == "123":
                        login = True
                        ret = func()
                        return ret   
                    
            return inner
        
        return auth2
    
    @auth("wechat")
    def jitter():
        print("欢迎回到抖音")
        
    @auth("QQ")
    def pipishrimp():
        print("皮皮虾等你好久了")
        
    jitter()
    pipishrimp()
    

    多个装饰器装一个参数

    def wrapper_1(f1):
        
        def inner_1(*args,**wkargs):
            print("wrapper_1,before f1")
            f1(*args,**wkargs)
            print("wrapper_1,after f1")
        
        return inner_1
    
    def wrapper_2(f2):
        
        def inner_2(*args,**wkargs):
            print("wrapper_2,before f2")
            f2(*args,**wkargs)
            print("wrapper_2,after f2,")
            
        return inner_2
    
    @wrapper_2
    @wrapper_1
    def func():
        print("666")
    
    func() 
    # 打印结果   
    '''
    wrapper_2,before f2
    wrapper_1,before f1
    666
    wrapper_1,after f1
    wrapper_2,after f2
    ''''
    

    递归函数 (recursion )

    • 在一个函数里在调用这个函数本身 / 递归的最大深度:998 , 最多执行到997
    • 人理解循环,神理解递归
    • 可以使用递归来遍历各种树形结构, 比如我们的文件夹系统. 可以使用递归来遍历该文件夹中的所有文件
    • 有规律的线性结构 有些适合用递归

    自定义递归深度

    import sys #  调用系统
    print(sys.setrecursionlimit(10000))  # 设置默认值递归深度
    def foo(n):
        print(n)
        n += 1
        foo(n)
    foo(1)
    

    有规律的数值差 / 递归

    def age(n):
        if n == 1:
            return 40
        else:
            return age(n-1)+2
    
    print(age(4))
    

    遍历列表 / 递归

    l1 = [1, 3, 5, ['22','python', 34, [33, 55, [11,33]]], [77, 88],66]
    
    def func(alist):
        for i in alist:
            if type(i) == list:
                func(i)
            else:
                print(i)
    func(l1)
    
    
    
  • 相关阅读:
    Codeforces714C【映射】
    Codeforces712C【贪心】
    Codeforces712B【= =】
    lightoj1259 【素数预处理】
    Codeforces482B【线段树构造】
    51nod 1348【next_permutation】
    hdoj5289【RMQ+二分】【未完待续】
    hdoj5875【二分+RMQ】
    RMQ算法
    AtCoder Regular Contest 061 DSnuke's Coloring
  • 原文地址:https://www.cnblogs.com/fanxss/p/11051634.html
Copyright © 2011-2022 走看看