zoukankan      html  css  js  c++  java
  • 开放封闭原则+装饰器

    一、开放封闭原则

    • 开发:对代码的拓展是开放的
    • 封闭:对源码的修改是封闭的
    • 不改变其原函数的代码以及调用方式的前提下,为其新增功能

    代码实现:

    #版本三,现在是ret加括号,不是index(),还得改
    import time
    #要求
    #封闭开放式原则
    #也就是要测试这个函数的执行时间,但是要符合封闭开放式原则
    #不改变其原函数的代码以及调用方式的前提下,为其新增功能
    def index():
        '''有很多代码'''
        time.sleep(2)
        print('你好tzh')
    
    #f 传入的是我们要测试的函数名,输入函数名即可(没得())
    def timer(f):
        def inner():
            start_time = time.time()
            f()     #调用要测试的函数
            enddd_time = time.time()
            print(F'当前函数:{f}的调用时间是{enddd_time-start_time}')
        return inner  #返回值不能是inner,谋得(),要返回函数名,不是调用函数
    
    #调用
    ret = timer(index)  #此时ret = inner,
    ret()  # inner() 调用原函数
    
    
    -------------语法糖--------------
    def timer(f):
        def inner():
            start_time = time.time()
            f()     #调用要测试的函数
            enddd_time = time.time()
            print(F'当前函数:{f}的调用时间是{enddd_time-start_time}')
        return inner  #返回值不能是inner,谋得(),要返回函数名,不是调用函数
    
    #语法糖,记住上面的函数得放上面,放下面会报错
    #语法糖,等同于timer = timer(index)下面直接调用即可
    @timer #被装饰函数
    def index():
        '''有很多代码'''
        time.sleep(2)
        print('你好tzh')
    #调用
    index()  # inner() 调用原函数
    
    ----------有返回值的怎么写呢?---------
    #版本6 ,被装饰函数带返回值
    def timer(f):
        def inner():
            start_time = time.time()
            # 此时f 才是index()真正的执行者,可以打印查看 print(f())  输出666
            #所以得把这个返回值传递给inner函数,因为下面的调用index实际上是调用inner,那要怎么给呢? r =f(),inner再返回r即可
            r = f()
            enddd_time = time.time()
            print(F'当前函数:{f}的调用时间是{enddd_time-start_time}')
            return r
        return inner
    
    @timer  == index= timer(f)
    def index():
        '''有很多代码'''
        time.sleep(0.6)
        print('你好tzh')
        return 666
    
    print(index())  #此时调用的任然是inner,返回值通过r,返回给inner函数,再赋值给print输出
    
    ----------被装饰函数带参数(一个参数那种)-----------
    #版本7
    def timer(f):
        def inner(n):
            start_time = time.time()
            #先把参数name传递给inner的n,再通过inner(n)传递给f(n),2次传递实现了带参装饰器
            # 此时的n = name =函数传入的数据
            #print(n)
            r = f(n)
            enddd_time = time.time()
            print(F'当前函数:{f}的调用时间是{enddd_time-start_time}')
            return r
        return inner
    
    @timer
    def index(name):
        '''有很多代码'''
        time.sleep(0.6)
        print(F'你好{name}')
        return 666
    print(index("tzh"))
    
    ----------被装饰函数带参数(一个参数那种)-----------
    #版本8
    def timer(f):
        # *--->定义时聚合
        def inner(*args,**kwargs):
            start_time = time.time()
            #加上万能参数,传入的参数就没限制了
            # * 调用时--->打散
            r = f(*args,**kwargs)
            enddd_time = time.time()
            print(F'当前函数:{f}的调用时间是{enddd_time-start_time}')
            return r
        return inner
    
    @timer
    def index(name,age):
        '''有很多代码'''
        time.sleep(0.6)
        print(F'你好{name}{age}')
        return 666
    print(index("tzh",18))
    

    标准版本装饰器:

    def wrapper(func):
        def inner(*args,**kwargs):
            '''添加额外的功能:执行被装饰函数之前的操作'''
            ret = func
            '''添加额外的功能:执行被装饰函数之后的操作'''
            return ret
        return inner
    

    二、装饰器

    • 字面意思:
      • 装饰:你买的新房子,如果装修,不但不影响你住,而且能让你在生活中增加了很多功能
      • 器:工具
    • 专业意思
      • 装饰器:完全遵循开放封闭原则
      • 装饰器:在不改变其原函数的代码以及调用方式的前提下,为其新增功能
      • 装饰器流程的本质:本质是闭包

    标准版装饰器:

    装饰器认证:

    login_status = {
        'username': None,
        'status': False,
    }
    
    def auth(x):
        def auth2(func):
            def inner(*args, **kwargs):
                if login_status['status']:
                    ret = func()
                    return ret
    
                if x == 'wechat':
                    username = input('请输入用户名:').strip()
                    password = input('请输入密码:').strip()
                    if username == '太白' and password == '123':
                        login_status['status'] = True
                        ret = func()
                        return ret
                elif x == 'qq':
                    username = input('请输入用户名:').strip()
                    password = input('请输入密码:').strip()
                    if username == '太白' and password == '123':
                        login_status['status'] = True
                        ret = func()
                        return ret
    
            return inner
    
        return auth2
    
    
    @auth('wechat')
    def jitter():
        print('记录美好生活')
    
    @auth('qq')
    def pipefish():
        print('期待你的内涵神评论')
    
  • 相关阅读:
    冒泡排序算法
    delphi 处理图片(剪切,压缩)
    delphi 创建DLL文件 及其调用和注意事项
    对属性的认识
    timer实现Grid自动换行(连续相同的id跳到下一行)
    Form1调用Unit2类中函数
    微信二次分享不显示摘要和图片
    location.search为空导致微信拿不到code的问题
    考虑一下微信跳转的登录流程如何修改-无感知
    微信7.0(2019年1月份之后,没法使用抓包了,也许是为了安全,所以联调出问题记得看后台日志)
  • 原文地址:https://www.cnblogs.com/hsyw/p/13764707.html
Copyright © 2011-2022 走看看