python笔记-函数6

  1. 开放封闭原则
1. 对扩展是开放的
任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能
2. 对修改是封闭的
例如,我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对函数内部进行修改,或者修改了函数的调用方式,很有可能影响其他已经在使用该函数的用户
  1. 装饰器
在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能
  1. 初识装饰器
版本一:需求是测试以下函数的执行效率
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')

start_time = time.time()
index()
end_time = time.time()
print(f'此函数执行效率为{end_time-start_time}')
#存在的问题:重复性代码太多,每测试一个新的函数的执行效率,就要重新再复制一遍代码。
版本二:解决代码重复的问题。
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')

def timmer(f):
    start_time = time.time()
    f()
    end_time = time.time()
    print(f'此函数执行效率为{end_time-start_time}')

timmer(index)
#虽然解决了代码重复的问题,但是不符合封闭性的原则,封闭性要求不改变原函数的代码,同时不改变原函数的调用方式
版本三:解决调用方式被改变的问题
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')

def timmer(f):
    def inner():
        start_time = time.time()
        f()
        end_time = time.time()
        print(f'此函数执行效率为{end_time-start_time}')
    return inner

index = timmer(index)
index()
#利用函数的闭包,解决了调用方式被改变的问题,但有些函数是需要返回值的,此版本的装饰器没有解决返回值问题
版本四:解决返回值问题
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')
    return True


def timmer(f):
    def inner():
        start_time = time.time()
        ret = f()
        end_time = time.time()
        print(f'此函数执行效率为{end_time-start_time}')
        return ret
    return inner

index = timmer(index)
result = index()
print(result)
#还有函数传参的问题待解决
版本五:解决传参问题
import time
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')
    return True

def home(name):
    time.sleep(3)
    print(f'欢迎访问{name}主页')

def timmer(f):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = f(*args, **kwargs)
        end_time = time.time()
        print(f'此函数执行效率为{end_time-start_time}')
        return ret
    return inner

home = timmer(home)
home('alex')
  1. python的语法糖
根据以上几个版本的代码,我们知道如果要给函数添加装饰器应该使用如下代码:
home = timmer(home)
如果你想给home加上装饰器,每次执行home之前你要写上一句:home = timer(home)这样你在执行home函数home('alex')才是真生的添加了额外的功能。但是每次写这一句也是很麻烦。所以,Python给我们提供了一个简化机制,用一个很简单的符号去代替这一句话。
import time
def timmer(f):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = f(*args, **kwargs)
        end_time = time.time()
        print(f'此函数执行效率为{end_time-start_time}')
        return ret
    return inner

@timmer
def index():
    time.sleep(2)
    print('欢迎访问博客园主页')
    return True

@timmer
def home(name):
    time.sleep(3)
    print(f'欢迎访问{name}主页')


index()
home('alex')

image
5. 标准的装饰器

def wrapper(func):
    def inner(*args, **kwargs):
        '''执行被装饰函数之前的操作'''
        ret = func(*args, **kwargs)
        '''执行被装饰函数之后的操作'''
        return ret
    return inner
posted on 2020-07-05 15:48  littleSUKI  阅读(98)  评论(0)    收藏  举报