返回函数

https://www.liaoxuefeng.com/wiki/1016959663602400/1017451447842528
函数作为返回值

闭包(closure)

https://zhuanlan.zhihu.com/p/453787908

匿名函数(lambda)

见python内置函数

装饰器

当需要增加一个函数的功能,又不希望直接改变其定义时,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)

本质:
所谓“装饰器”,就是封装了一个函数,并添加额外功能,然后返回一个新的函数

  1. def a_new_decorator(a_func):
  2. def wrapTheFunction():
  3. print("I am doing some boring work before executing a_func()")
  4. a_func()
  5. print("I am doing some boring work after executing a_func()")
  6. return wrapTheFunction
  7. def a_function_requiring_decoration():
  8. print("I am the function which needs some decoration to remove my foul smell")
  9. # 正常调用
  10. a_function_requiring_decoration()
  11. # 添加装饰
  12. a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
  13. #now a_function_requiring_decoration is wrapped by wrapTheFunction()
  14. a_function_requiring_decoration()
  15. #outputs:I am doing some boring work before executing a_func()
  16. # I am the function which needs some decoration to remove my foul smell
  17. # I am doing some boring work after executing a_func()

image.png

用@来实现装饰器
the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
image.png

标准示例:
这里的函数addition_func在调用时,实际是被warpTheFunction替代了,它重写了我们函数的名字和注释文档(docstring)。要想正常输出函数名,可以通过functools.wraps进行处理(第4行的@wraps(func))

  1. from functools import wraps
  2. def logit(func):
  3. @wraps(func)
  4. def warpTheFunction(*args, **kwargs):
  5. return func(*args, **kwargs) # 这里传可变参数实际上是没有意义的,addition_func定义时,只接受一个位置参数(但是可以用这种方式,透传可变参数)
  6. return warpTheFunction
  7. @logit
  8. def addition_func(x):
  9. return x + x
  10. result = addition_func(4)
  11. print(result) # 8
  12. print(addition_func.__name__) # addition_func(如果不import warps,得到的是warpTheFunction)

待参数的装饰器
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

  1. def log(text):
  2. def decorator(func):
  3. def wrapper(*args, **kw):
  4. print('%s %s():' % (text, func.__name__))
  5. return func(*args, **kw)
  6. return wrapper
  7. return decorator
  8. @log('execute')
  9. def now():
  10. print('2015-3-25')
  11. # 执行
  12. >>> now()
  13. execute now():
  14. 2015-3-25
  15. # 实际执行效果
  16. >>> now = log('execute')(now)

首先执行log(‘execute’),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数。