Python基础--装饰器

装饰器是python一个非常强大的功能,装饰器可以在不修改原代码的情况下给函数添加新的功能。要了解装饰器,首先要明白,函数的调用方式、函数即变量。装饰器利用了函数即变量,在其他函数调用原函数,来达到修饰的作用。
1.函数调用方式

def food():
	print("food")
food#不加上()是不会调用的
print(food)#打印函数,返回函数的地址
food()#调用

直接写food是不会调用food()函数,当打印函数名时会发现函数名就是一个地址,所以调用函数就是函数地址+(),那能不能把地址传进另一个函数执行呢。
2.函数作为变量传参

def food(func):
	print("food")
	func()#在函数内部执行传进来的函数
def fruit():
    print("fruit")
food(fruit)

在food()函数增加一个形参,把fruit()函数名(即地址)传进去,通过函数名+()进行调用。
3.简单的装饰器
现在想为food函数添加fruit函数的功能,但不修改food()的调用方式,不给food()增加参数。首先看下下面的程序,把food当做参数传进decorator中执行,在内部定义一个fruit()函数,decorator返回fruit函数的地址

def decorator(func):#func就是food的地址
	def fruit():
		func()
		print("fruit")
	return fruit#返回的是地址,不能加()
def food():
	print("food")
food=decorator(food)#有返回值,那么需要用变量接收
food()#eat其实就是fruit的地址,加()就是函数的调用

上面实现了不修改food()的调用方式给food函数增加了新的功能,python提供了语法糖的概念,用@来实现装饰器的功能

def decorator(func):
	def fruit():
		func()
		print("fruit")
	return fruit
@decorator#等价于food=decorator(food)
def food():
	print("food")
food()

4.被修饰函数带有参数的装饰器
被修饰的函数带有参数时,参数会传进下一个内部函数。

def decorator(func):#food
	def fruit(a,b):#food的参数
		func(a,b)
		print("fruit")
		print("sum=",a+b)#在内部调用传进来的参数
	return fruit
@decorator#等价于food=decorator(food)
def food(a,b):
	print("food")
food(1,2)

5.一个函数被多个装饰器装饰

def food(func):
    def inner():
        func()
        print("food")
    return inner

def fruit(func):
    def inner():
        func()
        print("fruit")
    return inner
@food#多个装饰器
@fruit
def eat():
    print("eat")
eat()

运行结果:
在这里插入图片描述
多个装饰器的调用非常有趣,被装饰的函数仅调用一次,并且离被装饰的函数越近,就先执行。
6.超级装饰器
装饰器和被装饰的函数都带有参数时,就需要在装饰器内部定义两层函数,装饰器本身已经带了参数,内部第一层接收被装饰的函数,内部第二层接收被装饰函数的参数

def dec1():#作为装饰器的参数
	print("dec1")
def dec2():#作为装饰器的参数
	print("dec2")
def decorator(dec1,dec2):#装饰器的参数
	def inner(func):#被装饰函数
		def sum(a,b):#被装饰函数的参数
			func(a,b)#调用被装饰的函数的参数
			print("sum=",a+b)
			dec1()#调用装饰器传进来的参数
			dec2()#调用装饰器传进来的参数
		return sum
	return inner
@decorator(dec1,dec2)#传入装饰器的参数
def food(a,b):
	print("food")
food(1,2)

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40850689/article/details/82827971