装饰器decorators(能力提高篇)

装饰器 decorators(专业提高篇)

什么是装饰器

  • 装饰器是一个函数,主要作用是来用包装另一个函数或类

装饰器的作用:

  • 在不修改被装饰的函数的源代码,不改变被装饰的函数的调用方式的情况下添加或改变原函数的功

能。

函数装饰器的语法:

def 装饰器函数名(fn):
语句块
return 函数对象
@装饰器函数名 <换行>
def 被装饰函数名(形参列表):
语句块

功能特点:

  • 不修改已有函数的源代码

  • 不修改已有函数的调用方式

  • 给已有函数增加额外的功能

用函数装饰器替换原函数myfun

def mydeco(fn):
    fn()
    print("装饰器函数被调用了,并返回了fx")
    def fx():
        print("fx被调用了")
        # return fn()
    return fx
@ mydeco
def myfun():
    print("函数myfun被调用")
myfun()
myfun()

当使用 @mydeco 语法装饰 myfun 函数时,实际上发生的是:

  1. myfun 函数作为参数传递给了 mydeco 装饰器。

  2. 在 mydeco 内部,首先调用了 fn() ,即此时调用了 myfun 函数,产生了输出:"函数myfun被调

用"。

     3.接着,打印了"装饰器函数被调用了,并返回了fx"。

    4.然后, mydeco 装饰器返回了新的函数 fx 。

因此,此刻 myfun 实际上被替换成了新的函数 fx 。这样的行为正是Python装饰器的特性之一:装饰器

可以修改函数的行为,甚至完全替换被装饰的函数。

基本装饰器

有参数的函数装饰器(在myfunc外加了一层)

def mydeco(fn):
    def fx():
        print("====这是myfunc被调用之前====")
        ret = fn()
        print("----这是myfunc被调用之后====")
    return ret
return fx
@mydeco
def myfunc():
    print("myfunc被调用.")
myfunc()
myfunc()
myfunc()

带参数的装饰器

def repeat(num):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num):
                func(*args, **kwargs)
        return wrapper
    return decorator
@repeat(3) # 应用装饰器,重复执行下面的函数3次
def greet(name):
    print(f"Hello, {name}!")
greet("Alice") # 调用被装饰的函数
  • repeat 是一个接受参数的装饰器工厂函数,它返回一个装饰器。

  • decorator 是真正的装饰器,它接受一个函数 func 作为参数。

  • wrapper 函数重复执行被装饰的函数 num 次。

  • 使用 @repeat(3) 应用装饰器,使 greet 函数被执行3次。

注意:带参数的装饰器需要三层函数,def wrapper(args, kwargs) 传入的是被修饰的函数的参数。

装饰器链

def uppercase(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper
​
def exclamation(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!"
    return wrapper
​
@exclamation
@uppercase
def say_hello(name):
    return f"Hello, {name}"
​
greeting = say_hello("Bob")
print(greeting) # 输出 "HELLO, BOB!"
  • uppercase 和 exclamation 是两个装饰器,分别将文本转换为大写并添加感叹号。

  • 使用 @exclamation 和 @uppercase 创建装饰器链,它们按照声明的顺序倒着依次应用。

  • say_hello 函数在执行前被链中的装饰器处理,最终输出 "HELLO, BOB!"。

4 类装饰器

class MyDecorator:
    def __init__(self, func):
        self.func = func
​
def __call__(self, *args, **kwargs):
    print("Something is happening before the function is called.")
    result = self.func(*args, **kwargs)
    print("Something is happening after the function is called.")
    return result
​
@MyDecorator # 应用类装饰器
def say_hello(name):
    print(f"Hello, {name}!")
​
say_hello("Charlie") # 调用被装饰的函数
  • MyDecorator 是一个类装饰器,它接受一个函数 func 作为参数并在 call 方法中执行额外

操作。

  • 使用 @MyDecorator 应用类装饰器,它将包装 say_hello 方法,使其在调用前后执行额外操作。

  • 与基本装饰器类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值