首页 Python基础入门视频教程 Python函数装饰器
pay pay

Python函数装饰器

日期: 二月 14, 2023, 8:19 a.m.
阅读: 283
作者: Python自学网-村长

摘要: Python函数装饰器

 一、普通函数

'''1.认识装饰器'''
# 通过一段代码给函数加上另一个功能
def dog():
    print('摇尾巴')

def cat():
    print('喵喵喵')

call = '狗'
if call == '狗':
    dog()
else:
    cat()

这时候有一个需求,必须是猫和狗的主人呼喊它们才会做出以上动作,就需要对指令发出者进行身份验证。如果直接在判断上采用身份验证,这样代码重用度会很低,如果在上面两个函数中写,如果验证代码过多,可能需要写好几遍。这时候我们可以再创建一个函数,在调用dog和cat函数的时候先调用身份验证函数,但是这样,我们的dog函数用在其他地方时如果不需要验证就会有冗余代码。

上面几种方案都有自己的缺点,我们可以试试前面学习的闭包函数来实现这个功能。

def func(f):
    def test():
        print('主人身份验证')
        f()
    return test

def dog():
    print('摇尾巴')
dog = func(dog)  # 这里的dog其实是test函数

def cat():
    print('喵喵喵')
cat = func(cat)

call = '狗'
if call == '狗':
    dog()  # ★★★这里的dog函数其实是test函数,所以先执行身份验证,然后又调用f()函数,也就是原来的dog()函数,也可以给这行的dog函数换个名字,好理解★★★
else:
    cat()

二、装饰器

# python还提供一种简单的装饰器写法,叫做语法糖,如下:
def func(f):
    def test():
        print('主人身份验证')
        f()
    return test

@func
def dog():
    print('摇尾巴')
# dog = func(dog)

@func
def cat():
    print('喵喵喵')
# cat = func(cat)

call = '狗'
if call == '狗':
    dog()
else:
    cat()

函数体不发生改变,增加了额外的功能,重用性高。装饰器内部必须使用闭包函数,否则当使用@时,装饰器就会被直接执行,注意执行顺序。

三、装饰器内的闭包函数

# 装饰器可以被叠加使用
def func(f):
    def test():
        print('主人身份验证')
        f()
    return test

def func2(f):
    def test2():
        print('=======')
        f()
    return test2

@func2
@func  # 可以叠加使用装饰器,先执行上面的装饰器
def dog():
    print('摇尾巴')

dog()  # 这里的dog函数其实是test和test2两个函数,而test和test2又返回来调用上面的dog()原始函数

四、传参

1.单个参数

# # 1.单个参数
def test(f):
    def test1(x):
        print('==========')
        f(x)
    return test1

@test
def func1(m):
    print(m)

func1(10)

2.多个参数

# 2.多个参数
def test(f):
    def test1(x, y):
        print('==========')
        f(x, y)
    return test1

@test
def func2(m, n):
    print(m, n)

func2(10, 5)

3.不定长参数

# 3.不定长参数
def test(f):
    def test1(*args, **kwargs):
        print('==========')
        f(*args, **kwargs)
    return test1

@test
def func2(a, b, c):
    # print(args, kwargs)
    print('*********')

func2(10, 5, c=6)  # 这里的c和上面func2的第三个形参名要一致

五、装饰有返回值的函数

def test(f):
    def test1(*args, **kwargs):  # 这里的test1函数要和被装饰函数func2的结构保持一致
        print('==========')
        res = f(*args, **kwargs)  # 这里相当于把被装饰函数的结果拿过来赋值,f(*args, **kwargs)的执行结果就是func2的返回值
        return res  # 没有返回值也可以这样写,返回结果就是None
    return test1

@test
def func2(a, b, c):
    # print(args, kwargs)
    print('*********')
    return a + b + c

print(func2(10, 5, c=88))

 

原创视频,版权所有,未经允许,切勿转载,违者必究!
回顶部