目录
装饰器是什么
装饰器简单说就是在不改变原有函数的基础上,对函数扩展一些功能。其本质是一个闭包。闭包函数有且只有一个参数,必须是函数类型,这样定义的函数才是装饰器。写装饰器时必须遵循开放封闭的原则,规定已经实现的功能代码不允许被修改,但是可以扩展。
装饰器的优点
- 不修改已有函数的源代码
- 不修改已有函数的调用方式
- 给已有函数增加额外的功能
装饰器的写法:
装饰器的基本雏形:
#我是装饰器函数
def decorator(fn): #fn表示被装饰函数
content = '我是装饰器函数'
def function():
print(content)
fn() #调用被装饰函数
return function
# 被装饰函数
def check():
print('我是被装饰函数')
decoratos = decorator(check)
decoratos()
'''
我是装饰器函数
我是被装饰函数
'''
其简单说就是将被装饰器函数但做一个参数传入装饰器函数中。在python中提供了一个装饰器更加简单的写法,叫语法糖
其格式为:
#装饰器函数
def 函数名字:
函数体
@装饰器函数名字
#被装饰函数
def 函数名字:
函数体
#调用被装饰函数
被装饰函数名字()
例子
#我是装饰器函数
def decorator(fn):
content = '我是装饰器函数'
def function():
print(content)
fn()
return function
# 被装饰函数
@decorator
def check():
print('我是被装饰函数')
check()
#等同于decoratos = decorator(check)
# decoratos()
'''
我是装饰器函数
我是被装饰函数
'''
可以发现,被装饰函数定义前加一个@装饰器函数名字,可以省略取调用函数的过程,使代码更加简洁。
多个装饰器函数的使用:
与单个装饰器方法差不多,只是在被装饰函数前加@装饰器函数名字即可,需要几个@几个就行。但是需要注意的是:装饰器的装饰过程是从内而外的,离被装饰函数最近的先装饰,然后外面的装饰器在进行装饰,以此类推。
例子:
def decorator1(fn):
content = '我是装饰器函数1'
def function():
print(content)
fn()
return function
def decorator2(fn):
content = '我是装饰器函数2'
def function():
print(content)
fn()
return function
# 被装饰函数
@decorator2
@decorator1
def check():
print('我是被装饰函数')
check()
'''
我是装饰器函数2
我是装饰器函数1
我是被装饰函数
'''
装饰带参数的函数时
当装饰器带参数时,则需要在使用装饰器装饰函数的时候可以传入指定参数。
例子:
def decorator1(fn):
def function(a,b): #定义时传入形式参数
print('%d+%d的和是'%(a,b))
fn(a,b) #调用时传入实际参数
return function
@decorator1
#被装饰函数
def check(a,b): #带参数的被装饰函数
c=a+b
print('%d'%c)
check(2,3)
'''
2+3的和是
5
'''
装饰带返回值的函数时
与带参数的装饰器类似,使用装饰器装饰函数时返回值即可
例子
def decorator1(fn):
def function(a,b): #定义时传入形式参数
print('%d+%d的和是'%(a,b))
c=fn(a,b) #调用时传入实际参数
return c #返回值
return function
@decorator1
#被装饰函数
def check(a,b): #带参数的被装饰函数
c=a+b
return c #带返回值的被装饰函数
sum=check(2,3)
print(sum)
'''
2+3的和是
5
'''
当装饰器有参数时
由于装饰器的参数只有有一个并且是函数类型,所以如果装饰器需要参数时,则只能在参数是函数类型的位置外面再嵌套一个外部函数,而这个外部函数则可以传入装饰器的参数。在语法糖括号里面传入实际参数即可
例子:
def decdecorator1(x):
def decorator2(fn):
def function(a,b):
if x=='+':
print('这是加法运算!')
else:
print('这不是加法运算!')
c=fn(a,b)
print('%d+%d的和是'%(a,b))
return c
return function
return decorator2
@decdecorator1('+')
#被装饰函数
def check(a,b): #带参数的被装饰函数
c=a+b
return c
c=check(4,7)
print(c)
'''
这是加法运算!
4+7的和是
11
'''
通用装饰器
在装饰器中,还有一种通用装饰器,可以实现传入多少个参数都可以正常运行,其原理就是在传入参数时使用单星号(*)和双星号(**)对参数进行打包。
格式:
def decdecorator(fn):
def function(*args,**kwargs): #对数据进行打包
'''代码'''
value=fn(*args,**kwargs) #返回值
return value
return function