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('期待你的内涵神评论')
    
  • 相关阅读:
    sublime-生成html1.0
    sublime代码片段
    单色半透明-兼容IE7
    IE
    身心被掏空
    屏幕适配的方法
    宫格布局实例(注意jquery的版本号要统一)
    宫格布局实例(注意jquery的版本号要统一)2
    有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数。
    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
  • 原文地址:https://www.cnblogs.com/hsyw/p/13764707.html
Copyright © 2011-2022 走看看