本章内容
- 高阶函数
- 装饰器
前言
接着上一篇函数进行整理。。
一、高阶函数
高阶函数就是将一个函数以参数的形式传入另一个函数
1 def main_func(func): 2 # 定义一个主函数,并设置一个参数func 3 4 return func 5 # 返回func的值,因为我需要传入一个函数,即返回func的返回值 6 7 def func(): 8 # 定义一个函数作为参数传入主函数 9 10 return "Lyon" 11 # 返回 "Lyon" 给func() 12 13 res = main_func(func()) 14 # res接收main_func的返回值,将func()的返回值作为参数传入main_func函数 15 16 print(res) 17 # 打印结果 : Lyon
二、装饰器
什么是装饰器?听名字我们就知道是一个进行装饰的工具,装饰什么?当然是装饰函数,即给原来的函数加上一些功能。
装饰器是由函数去生成的,用于装饰某个函数或者方法或者类(类以后再说),他可以让这个函数在执行之前或者执行之后做一些操作。反正就是给函数加功能。
语法:
1. def decorator(func) :
2. pass
3. @decorator @ + "函数名" 是python中的一种语法糖
4. def func() :
5. pass
学习装饰器,首先得知道上述 @ + "函数名" 这个语法糖 到底进行了些什么操作。
就利用上述语法作为例子,来说一下语法糖 进行的操作:
首先 @ + "函数名" ---> 将该操作下面的函数的函数名(即func)作为参数传入装饰器函数(即decorator),等装饰器函数执行完之后又将装饰器函数的返回值返回给函数名。
一个等式:
@decorator = decorator(func) , func = decorator的返回值
- 第一个版本
1 def decorate(func): 2 # 定义装饰器函数,func参数接收被装饰函数名 3 4 return func() 5 # 返回function的返回值给decorate 6 7 @decorate #给function函数装上decorate函数 8 def function(): 9 # function最后会接收decorate的返回值 10 11 return "装饰成功!" 12 # function的返回值为 "装饰成功!" 13 14 res = function 15 # 进行调用,不要加括号,加了会报错。----> 传递过程在下面 16 17 print(res) 18 # 打印结果 :"装饰成功!"
函数的调用其实就是调用函数名,而函数名其实就是一个内存地址,方式是通过 括号"( )"进行调用。
传递过程:function --> decorate(function) --> function() --> decorate --> function
传递过程注解:函数名 --> decorate中的参数 --> 加括号进行调用 --> 返回decorate --> 返回函数名
通过传递过程我们可以知道,在过程中function已经进行了调用,所以最后我们进行调用的时候是不能在加括号的,因为function此时已经是运行后拿到了返回值。
- 第二个版本
1 def decorate(func): 2 # 定义装饰器函数,func参数接收被装饰函数名 3 4 def inner(): 5 # 这一步的作用通过调用方式基本能看出来了 6 7 return func() 8 # 将function的返回值给inner 9 10 return inner 11 # 将inner内存地址返回给decorate 12 13 @decorate #给function函数装上decorate函数 14 def function(): 15 # function最后接收的是一个内存地址 16 17 return "装饰成功!" 18 # function的返回值为 "装饰成功!" 19 20 res = function() 21 # 利用 ( ) 调用其函数名,函数名现在对应的是inner的内存地址 22 23 print(res) 24 # 打印结果 :"装饰成功!"
一般我们用的是第二个版本,因为最后调用方式跟我们进行函数调用的方式是一样的。
*语法糖:指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜”的语法。语法糖主要是为程序员提供更实用的编码方式,提高代码的可读性,并有益于更好的编码风格。
通过以上基本已经了解了装饰用的用法,以及原理。
更多示例:
1 def decorator1(func): 2 def inner(): 3 return func() 4 return inner 5 6 def decorator2(func): 7 def inner(): 8 return func() 9 return inner 10 11 @decorator1 12 @decorator2 13 def function(): 14 print("执行函数...") 15 function()
多个装饰器装饰同一个函数
1 def decorator(func): 2 def inner(name): 3 #被装饰函数参数所放位置 4 5 return func(name) 6 return inner 7 8 @decorator 9 def function(name): 10 print("my name is %s" % name) 11 12 function("Lyon")
被装饰函数带有参数
以上基本完成了装饰器的功能。这里的一个中间过程 是将 被装饰函数进行了一次调用,所以被装饰函数中的元信息(如:函数的注释信息)并没有赋值进装饰器函数内部。
如果需要把元信息也赋值进装饰器,那个可以使用 @functools.wraps
1 def decorator(func): 2 @function.wraps(func) 3 def inner(name): 4 return func(name) 5 return inner 6 7 @decorator 8 def function(name): 9 """ 10 这就是一个不起眼的函数 11 :param name: 12 :return: 13 """ 14 print("my name is %s" % name) 15 function("Lyon")
functools.wraps