Python 装饰器

装饰器概念

装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为。

装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。

说白了装饰去本质上是一个 Python 函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

装饰器的语法使用 @decorator_name 来应用在函数或方法上。

Python 还提供了一些内置的装饰器,比如 @staticmethod 和 @classmethod,用于定义静态方法和类方法。

python 复制代码
def print_function_name(func):
    print(func.__name__)
    return func

@print_function_name
def func1():
    print("函数1运行")


# 函数在声明时,如果我们添加了装饰器,那么装饰器在声明时就被调用了
func1()

# 结果是 func1 函数1运行

装饰器的应用场景

  • 日志记录: 装饰器可用于记录函数的调用信息、参数和返回值。
  • 性能分析: 可以使用装饰器来测量函数的执行时间。
  • 权限控制: 装饰器可用于限制对某些函数的访问权限。
  • 缓存: 装饰器可用于实现函数结果的缓存,以提高性能。

装饰器函数中的参数传递

我们使用一个日志的打印的案例来说明

python 复制代码
def print_log(func):
    print(func)
    return func

@print_log
def func1(a,b):
    print("函数1被运行",a,b)
    
func1(1,2)

函数参数传递演变1,func1 如果不调用,inner 不会被执行

python 复制代码
def print_log(func):
    print(func)
    def inner(x,y):
        x += 1
        y += 1
        print("参数列表是:",x,y) 
    return inner

@print_log
def func1(a,b):
    print("函数1被运行",a,b)
    
func1(1,2)  # 结果: 
                # 参数列表是: 2 3
                # <function func1 at 0x1044f68e0>

函数参数传递演变2

python 复制代码
def print_log(func):
    print(func)
    def inner(x,y):
        print("参数列表是:",x,y)
        return func(x,y)
    return inner

@print_log               
def func1(a,b):
    print("函数1被运行",a,b)
    return a + b
    
r = func1(10,20)
print(r) 

# 执行结果是:首先装饰器一声明,就会执行:<function func1 at 0x1046228e0>
#           func1 方法调用,就会执行 inner 参数列表是: 10 20,接着执行 函数1被运行 10 20 , 接着是 None

调用 func1 ,需要在 inner 将结果返回给 r

python 复制代码
def print_log(func):
    print(func)
    def inner(x,y):
        print("参数列表是:",x,y)
        return func(x,y)
    return inner

@print_log               
def func1(a,b):
    print("函数1被运行",a,b)
    return a + b
    
r = func1(10,20)
print(r) 

# 执行结果是:首先装饰器一声明,就会执行:<function func1 at 0x1046228e0>
#           func1 方法调用,就会执行 inner 参数列表是: 10 20,接着执行 函数1被运行 10 20 , 接着是 30

函数参数传递演变3---动态参数

python 复制代码
def print_log(func):
    print(func)
    def inner(*args,**kwargs):
        print("参数列表是:",args,kwargs)
        return func(*args,**kwargs)
    return inner

@print_log
def func1(a,b,c,d,e=1,f=2):
    print("函数1被运行",a,b,c,d)
    return a + b+c+d
    
r = func1(10,20,30,40,e=1,f=2)
print(r) 

演变 4

python 复制代码
def print_log(type):
    print(type)
    def warpper(func):
        print(func)
        def inner(*args,**kwargs):
            if type=="控制台":
                print("参数列表是:",args,kwargs)
            elif type == "文件":
                print("我已经把日志输出到文件中了")
            return func(*args,**kwargs)
        return inner 
    return warpper


@print_log("控制台")
def func1(a,b,c,d,e=1,f=2):
    print("函数1被运行",a,b,c,d)
    return a + b+c+d
    
r = func1(10,20,30,40,e=1,f=2)
print(r)


@print_log("文件")
def func2(a,b):
    print("函数1被运行",a,b)
    return a + b
    
r = func2(100,200)
print(r)

理解 yield 关键字与生成器对象

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

调用一个生成器函数,返回的是一个迭代器对象。

python 复制代码
def countdown():
    print("函数func2被调用1")
    yield 2
    print("函数func2被调用2")
    yield 3
    print("函数func2被调用3")
    yield 4

# 创建生成器对象
f2 = countdown()
print(f2)
# 启动生成器对象
r2 = f2.__next__()
print(r2)
r3 = f2.__next__()
print(r3)
r4 = f2.__next__()
print(r4)

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

python 复制代码
def countdown():
    print("函数func2被调用1")
    yield 2
    print("函数func2被调用2")
    yield 3
    print("函数func2被调用3")
    yield 4

# 创建生成器对象
f2 = countdown()

for i in range(5):
    print(i)

for f in f2:
    print(f)

生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。

python 复制代码
def func3():
    num = yield 1
    print(num)
    num1 = yield num + 10
    print(num1)
    yield  num1 + 10

f3 = func3()
print(f3)
r1 = f3.send(None)
print("r1的值",r1)
r2 = f3.send(2)
print("r2的值",r2)
r3 = f3.send(3)
print("r3的值",r3)
相关推荐
databook8 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar9 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780519 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_9 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机16 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机17 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机17 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i17 小时前
drf初步梳理
python·django
每日AI新事件17 小时前
python的异步函数
python