标签:知识 语法糖 需要 代码 使用 就是 span 需求 函数名
现有如下函数:
def fun1():
print(‘...fun1()...‘)
def fun2():
print(‘...fun2()...‘)
#调用函数
fun1()
fun2()
需求:需要给以上两个函数添加记录日志功能
方法一:函数调用
def logging():
print(‘...logging...‘)
def fun1():
print(‘...fun1()...‘)
logging()
def fun2():
print(‘...fun2()...‘)
logging()
#调用函数
fun1()
fun2()
分析:上面这种方式适合少量函数调用,如果有n个地方需要调用logging()函数,那么得手动调用n次,比较麻烦,而且在fun1()中调用loggin()也相当于修改了fun1()的内容。
方法二:高阶函数(函数名作为参数传递给另一个函数)
def logging(fun):
fun()
print(‘...logging...‘)
def fun1():
print(‘...fun1()...‘)
def fun2():
print(‘...fun2()...‘)
#调用函数
logging(fun1)
logging(fun2)
分析:该方法是高阶函数的用法,将函数名当做参数传递给另一个函数,优点是没有修改源代码,缺点是该方法修改了调用的方式。
方法三:高阶函数(返回值中包含函数名)
def logging(fun):
print(‘...logging...‘)
return fun
def fun1():
print(‘...fun1()...‘)
def fun2():
print(‘...fun2()...‘)
#调用函数
fun1 = logging(fun1)
fun2 = logging(fun2)
fun1()
fun2()
该方法的优点是没有改变原有函数的调用方式,但是改变的原有输出顺序。
方法四:嵌套函数
def logging(fun):
def dec(fun):
return fun()
dec(fun)
print(‘...logging...‘)
def fun1():
print(‘...fun1()...‘)
def fun2():
print(‘...fun2()...‘)
#调用函数
logging(fun1)
logging(fun2)
该方法优点是没有修改源代码,但是调用方式改变了。
总结:
如果需要不修改源代码、不修改调用方式,则需要使用高阶函数+嵌套函数一起,由此引入了装饰器的概念。
装饰器
定义:本质是函数(装饰其他函数),就是为其他函数添加附加功能。
原则:1.不能修改被装饰函数的源代码
2.不能修改被装饰函数的调用方式
装饰器知识储备:
1.函数即“变量”
2.高阶函数
a:函数名作为实参传给另一个函数(在不修改源代码的情况下为其新增功能)
b:返回值中包含函数名(不修改函数的调用方式)
3.嵌套函数
高阶函数+嵌套函数=>装饰器
使用高阶函数+嵌套函数修改上面需求:
def logging(fun):
def dec():
fun()
print(‘...logging...‘)
return dec
def fun1():
print(‘...fun1()...‘)
def fun2():
print(‘...fun2()...‘)
#调用函数
fun1 = logging(fun1)
fun2 = logging(fun2)
fun1()
fun2()
装饰器语法糖:即在函数前使用@函数名
使用语法糖修改以上代码:
def logging(fun):
def dec():
fun()
print(‘...logging...‘)
return dec
@logging
def fun1():
print(‘...fun1()...‘)
@logging
def fun2():
print(‘...fun2()...‘)
#调用函数
fun1()
fun2()
如上案例中的@logging可以理解为:fun1 = logging(fun1)
标签:知识 语法糖 需要 代码 使用 就是 span 需求 函数名
原文地址:https://www.cnblogs.com/jmwm/p/9759251.html