【AI_Python基础_09装饰器】


前言

本章内容主要是介绍装饰器相关的知识:
装饰器是Python中一种特殊的函数,用于修改其他函数的行为。它可以在不修改原始函数代码的情况下添加额外的功能。


一、知识回顾

在介绍装饰器之前,回顾装饰器所需要的三个知识点:

  • 函数可以作为参数进行传递
def func():
	print("我是函数")
def gg(fn):		#	fn是参数也是函数
gg(func)

我是函数
  • 函数可以作为返回值进行返回
def func():
    def inner():
        print("123")
    return inner

ret = func()    #   此时ret()就是inner()
ret()

123
  • 函数名称可以当成变量一样进行赋值操作
def func1():
    print("我是函数1")

def func2():
    print("我是函数2")

func1 = func2
func1()

我是函数2

回顾并理解了这三个知识点,理解装饰器就会变得很简单

二、装饰器的语法

装饰器是一个函数,它接受一个函数作为参数,并返回另一个函数。通常情况下,装饰器使用 @ 符号以及装饰器函数的名称来修饰目标函数。
装饰器其实本质上是一个闭包,参数为局部变量,但是该局部参数为函数。

"""
定义两个”游戏“函数
"""
def DNF():
	print("你好啊,我叫赛利亚,今天又是美好的一天!")

def LOL():
	print("德玛西亚!!!")
"""
现在我想给我的游戏开个”外挂“
"""
print("打开外挂")
DNF()	#	启动游戏DNF
print("关闭外挂")
print("打开外挂")
LOL()	#	启动游戏LOL
print("关闭外挂")		# 每次打游戏都需要手动打开外挂,很烦。让管家帮我
def guanjia(game):
	def inner():
		print("打开外挂")
		game()
		print("关闭外挂")
	return inner
DNF = guanjia(DNF)
LOL = guanjia(DNF)	
"现在就可以玩儿外挂游戏了,但是我可以直接把我的游戏改成自带外挂的游戏,把我的游戏@guanjia封装一下。"
ef guanjia(game):
	def inner():
		print("打开外挂")
		game()
		print("关闭外挂")
	return inner
@guanjia	
def DNF():
	print("你好啊,我叫赛利亚,今天又是美好的一天!")
@guanjia
def LOL():
	print("德玛西亚!!!")

DNF()
LOL()

打开外挂
你好啊,我叫赛利亚,今天又是美好的一天!
关闭外挂
打开外挂
德玛西亚!!!
关闭外挂

三、装饰器的参数传递

带参数的装饰器是指可以接受参数的装饰器函数。通过在装饰器函数外再包一层函数,这个外层函数用来接受参数,并返回装饰器函数。这样可以根据传入的参数来定制装饰器的行为,使得装饰器具有更大的灵活性和可定制性。

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(n=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

在这个示例中,repeat函数是一个带参数的装饰器。它接受一个参数n,表示重复执行目标函数的次数。在装饰器内部,定义了一个decorator函数作为装饰器函数,它接受目标函数func作为参数,并返回一个新的函数wrapper。在wrapper函数内部,利用for循环执行目标函数func,重复n次。

通过使用@repeat(n=3)语法,我们将repeat装饰器应用到greet函数上,并传入参数n=3。这样,greet函数在被调用时会重复打印Hello, Alice!三次。

这种带参数的装饰器可以用于很多场景,例如重试机制、缓存设置等,通过传入不同的参数可以实现不同的功能定制。

四、装饰器的嵌套

装饰器可以进行嵌套,即一个装饰器可以包含另一个装饰器。在使用多个装饰器修饰同一个函数时,装饰器的调用顺序是由内向外的。

举个例子,我们定义了两个装饰器函数make_boldmake_italic,它们分别用来给文本加粗和加斜体标签。然后,我们在greet函数上应用了这两个装饰器,实现了对greet函数返回值的同时加粗和加斜体处理。

当调用greet()函数时,实际上是调用了经过两个装饰器装饰后的wrapper函数。首先,make_italic装饰器将greet函数包裹在了一个带有斜体标签的wrapper函数中,然后make_bold装饰器又将这个斜体文本包裹在了一个带有粗体标签的wrapper函数中。最终的效果是,打印出来的文本既有斜体又有粗体效果。

def make_bold(func):
    def wrapper():
        return "<b>" + func() + "</b>"
    return wrapper

def make_italic(func):
    def wrapper():
        return "<i>" + func() + "</i>"
    return wrapper

@make_bold
@make_italic
def greet():
    return "Hello, world!"

print(greet())

五、类装饰器

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 方法,使其在调用前后执行额外操作。
  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值