Day13

总结

闭包函数

# 1.闭包函数的特征
	1.闭:定义在函数内部的函数
    2.包:内部函数使用外层函数名称空间的名字
    def outer():
        x = 123
        def inner():
            print('inner',x)  # inner 123
        return inner
    x = 321
    res = outer()
    res()

闭包函数的应用

# 函数传参的方式:1.形参  2.闭包
# 形参:
	def func(username):
    	print(username)
    func('username')

#闭包:
	def outer():
        x = 123
        def inner():
            print('inner',x)
        return inner
    x = 321
    res = outer()
    res()

装饰器

# 装饰器的本质
	在不改变被装饰对象原有的调用方式和内部代码情况下给被装饰对象添加新的功能
    
# 装饰器的原则
	1.对扩展开放
    2.对修改关闭
    
 # 用时间戳运算函数运行时间举例
    import time
    def func():
        time.sleep(3)  # 延迟3秒打印
        print('运行完毕')
    start_time = time.time()  # 函数开始的时间戳
    func()
    end_time = time.time()  # 函数结束的时间戳
    print('函数运行时间:%s ' % (end_time - start_time))

简易版本装饰器

 # 把运算部分用函数封装起来
    import time
    def index(func):
        start_time = time.time()  # 函数开始的时间戳
        func()
        end_time = time.time()  # 函数结束的时间戳
        print('函数运行时间:%s ' % (end_time - start_time))
        
    def home():
        time.sleep(3)  # 延迟3秒运行
        print('运行完毕')

    index(home)
# 但是封装成函数之后调用方式改变,不满足装饰器原则,所以下面采用另一种方式

	import time

    def home():
        time.sleep(3)  # 延迟3秒运行
        print('运行完毕')
    def outer(func):
        def inner():
            start_time = time.time()  # 函数开始的时间戳
            func()  # 调用真正的honme函数
            end_time = time.time()  # 函数结束的时间戳
            print('函数运行时间:%s ' % (end_time - start_time))
        return inner

    home = outer(home) 不改变调用方式
	home()

进阶版装饰器

# 运用所学方式让参数规范一点
import time

def home():
    time.sleep(3)  # 延迟3秒运行
    print('运行完毕')
def outer(func):
    def inner(*args, **kwargs):
        start_time = time.time()  # 函数开始的时间戳
        func(*args, **kwargs)  # 调用真正的honme函数
        end_time = time.time()  # 函数结束的时间戳
        print('函数运行时间:%s ' % (end_time - start_time))
    return inner

home = outer(home)
home()

:

最终版本

# 上一版的装饰器没有返回值,将返回值模拟写出来
import time

def home():
    time.sleep(3)  # 延迟3秒运行
    print('运行完毕')
def outer(func):
    def inner(*args, **kwargs):
        start_time = time.time()  # 函数开始的时间戳
        home = func(*args, **kwargs)
        end_time = time.time()  # 函数结束的时间戳
        print('函数运行时间:%s ' % (end_time - start_time))
        return home
    return inner

home = outer(home)
home()

装饰器模板

'''编写装饰器其实有一套固定的代码 不需要做任何理解'''
def outer(func_name):  # func_name用于接收被装饰的对象(函数)
    def inner(*args, **kwargs):
        print('执行被装饰函数之前 可以做的额外操作')
        res = func_name(*args, **kwargs)  # 执行真正的被装饰函数
        print('执行被装饰函数之后 可以做的额外操作')
        return res  # 返回真正函数的返回值
    return inner

装饰器语法糖

# 语法糖可以使代码更简洁
def outer(func_name):
    def inner(*args, **kwargs):
        print('执行函数之前的操作')
        res = func_name(*args, **kwargs)
        return res
    return inner

@outer  # 等价于 index = outer(index)
def index(*args, **kwargs):
    print('from index')
'''
语法糖内部原理
    1.使用的时候最好紧跟在被装饰对象的上方
    2.语法糖会自动将下面紧挨着的函数名传给@后面的函数调用
''' 

装饰器修复技术

from functools import wraps  # 固定搭配
def outer(func_name):
    @wraps(func_name)  # 固定搭配
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的操作')
        res = func_name(*args, **kwargs)
        return res
    return inner
@outer
def index():
    print('from index')
@outer
def home():
    '''这是home函数的注释'''
    print('from home')

装饰器有点绕,还得花时间继续深入

:

posted @ 2022-03-19 14:48  有梦想的阿九  阅读(59)  评论(0)    收藏  举报