开放封闭原则+装饰器

一、开放封闭原则

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

代码实现:

#版本三,现在是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('期待你的内涵神评论')
原文地址:https://www.cnblogs.com/hsyw/p/13764707.html