- 问题:定义了一个函数,想在运行时动态增加功能,但又不想改动函数本身的代码。
示例:希望对下列函数调用增加log功能,打印出函数调用:
def f1(x):
return x * 2
def f2(x):
return x * x
def f3(x):
return x * x * x
方法1:直接修改原函数
def f1(x):
print ('call f1()')
return x * 2
def f2(x):
print ('call f2()')
return x * x
def f3(x):
print ('call f3()')
return x * x * x
思考: 有没有更简单的方法?
——高阶函数 :可以接收函数作为参数,可以返回函数,那么是否可以接收一个函数,对其包装,然后返回一个新函数?
方法2 :通过高阶函数返回新函数
def f1(x):
return x * 2
def new_fn(f): #装饰器函数
def fn(x):
print ('call' + f._name_ + '()') #函数对象有一个__name__属性,可以拿到函数的名字:
return f(x)
return fn
# 调用
(1) g1 = new_fn(f1)
print (g1(5))
(2) f1 = new_fn(f1)
print (f1(5)) # f1的原始定义函数被彻底隐藏了
2. Python 内置的@语法就是为了简化装饰器调用:
@new_fn def f1(x):
def f1(x): ===> return x * 2
return x * 2 f1 = new_fn(f1)
3. 装饰器的作用
可以极大地简化代码,避免每个函数编写重复性代码。
打印日志:@log
检测性能:@performance
数据库事物:@transaction
URL路由:@post('/register')