形式

1
2
3
4
5
def decorator(func):
def wrapper(*args,**kw):
print('This is an extra function')
func(*args,**kws)
return wrapper()

栗子:将f1函数不改变函数体条件下增加打印当前调用时间功能

1
2
3
4
5
6
7
8
9
10
11
import time
def decorator(func): # 传入原函数
def wrapper():
print(time.time()) # 增加的新功能
func() # 确保函数的原功能的进行
return wrapper # 返回内部函数(闭包)

@decorator # @语法糖
def f1():
print('This is a function')
f1()

1581497430.8031123
This is a function

如果不用装饰器

1
2
3
4
5
6
7
import time
def new_func(func):
print(time.time())
func()
def f1():
print('This is a function')
new_func(f1)

无法看出新功能的添加,而是通过新函数调用原函数
将新函数打包进入装饰函数,通过装饰函数传入原函数,返回打包的新功能函数,形成闭包。进而可使用@语法糖

优化:支持不同个数参数

  • 在内部打包函数中传入可变参数
  • 在打包函数中老函数的调用中传入可变参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import time
def decorator(func):
def wrapper(*args): # *可变参数(args代表一组参数)
print(time.time())
func(*args) # 添加可变参数
return wrapper

@decorator # @语法糖
def f1(func_name):
print('This is a function '+func_name)

@decorator
def f2(func_name1,func_name2):
print('This is another funcion '+func_name1+'' +func_name2)
f1('test1')
f2('test2','test3')
1581498420.7538562
This is a function test1
1581498420.7538562
This is another funcion test2 test3

优化:支持关键字参数

  • 内部打包函数传入“**关键字参数”
  • 调用老函数时,传入“**关键字参数”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import time
def decorator(func):
def wrapper(*args): # 添加关键字参数
print(time.time())
func(*args) # 添加关键字
return wrapper

@decorator # @语法糖
def f1(func_name):
print('This is a function '+func_name)

@decorator
def f2(func_name1,func_name2):
print('This is another funcion '+func_name1+'' +func_name2)

@decorator
def f3(**kw):
print(kw)

f1('test1')
f2('test2','test3')
f3(a=1,b=2,c=3)
1581499561.933681
This is a function test1
1581499561.933681
This is another funcion test2test3
1581499561.933681
{'a': 1, 'b': 2, 'c': 3}

关键字参数:

  • 关键字参数允许你传入0个或任意多个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
  • 对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数,以扩展函数的功能
  • 至于到底传入了哪些关键字参数,就需要在函数内部通过kw检查
1
2
3
def fun(**kw):
print(kw)
fun(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}

思想

不去改动函数内部代码的实现,改变函数的行为
满足开闭原则
满足函数复用性