python进阶之闭包装饰器

一.什么是闭包装饰器?在什么场景下用到?

闭包装饰器:对旧功能/代码,在最小源代码改造情况下进行功能升级.装饰器也叫[语法糖]

比如:例如我们需要对数据库的操作,额外增加事务的处理.就可以用到装饰器来解决.

例子:

# 定义装饰器,用来对旧代码升级/加强
def outer_func(func):
    def wrapper(*args,**kwargs):
        print("代码加强【开启事务】")

        # 调用原始函数
        func(*args,**kwargs)

        print("代码加强【关闭事务】")

    return wrapper

@outer_func
def crud():
    print("对数据库的增删改查操作")

crud()

注意: 使用装饰器,我们对原始的crud()方法内部没有做任何的改变

二.闭包有什么特点?

1.函数嵌套(在外部函数里面定义了一个内部函数)

2.外部函数return返回了内部函数

3.内部函数里面使用了外部函数的变量(包括外部函数的特点)

例子:

def func_outer():
    # 定义一个全局变量 count,来记录 sub 函数的调用次数
    count = 0

    def sub(a, b):
        """计算两个数之差"""
        nonlocal count
        count += 1 # count = count + 1
        print(f'第{count}次调用该函数')
        return a - b

    return sub

# 注意:这里调用外部函数,是为了拿到内部函数对象
func = func_outer()
print(func)
func(1, 2)
func(2, 3)
func(3, 5)

三.通用装饰器的展示(推荐使用)

# 装饰器通用写法
import time


def get_time(func):
    def wrapper(*args,**kwargs):
        # 加强代码
        s = time.time()

        # 调用原始函数
        result = func(*args,**kwargs)

        # 加强代码
        e = time.time()
        print(f"运行耗时{e - s}")

        return result


    return wrapper

@get_time
def fun1(m,n):
    _sum = 0
    for i in range(m,n):
        _sum += i
    return _sum


_sum = fun1(1, 10000000)
print(_sum,type(_sum))

四.带参装饰器

"""
@装饰器(参数)
本质:带参装饰器的本质,是在普通的装饰器的外面,又包了一层函数
"""
import time

"""普通装饰器 2层函数嵌套,无需最外层的函数包裹
装饰器带参数,就在2层基础上,再加一层,专门接收装饰器的参数
"""
def func_outer(float_decimals):
    """接收装饰器的参数"""
    """返回 下一层函数(名字)"""
    def get_time(func):
        """接收被装饰的函数"""
        """返回 内层函数(名字)"""
        def wrapper(*args, **kwargs):
            """接收被装饰函数的参数"""
            """对被装饰的函数额外加功能,会用到外层函数的参数"""
            """运行被装饰的函数"""
            """返回 被装饰函数运行的结果"""
            s1 = time.time()
            result = func(*args, **kwargs)
            s2 = time.time()
            # 控制小数的位数
            ret = round(s2-s1, float_decimals)
            print(f'函数的执行时间为:{ret}秒')
            return result
        return wrapper
    return get_time

@func_outer(float_decimals=3) # 控制输出的小数位数
def func1():
    """func1函数无参数,也无返回值"""
    _sum = 0
    for i in range(1000000):
        _sum += i
    return _sum

print(func1())

猜你喜欢

转载自blog.csdn.net/MSJ3917/article/details/135286769
今日推荐