首页 > 代码库 > Python - 函数进阶之装饰器

Python - 函数进阶之装饰器

本章内容

  1. 高阶函数
  2. 装饰器

前言

  接着上一篇函数进行整理。。

一、高阶函数

  高阶函数就是将一个函数以参数的形式传入另一个函数

 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 = function15 # 进行调用,不要加括号,加了会报错。----> 传递过程在下面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 inner11     # 将inner内存地址返回给decorate12 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 inner10 11 @decorator112 @decorator213 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

 

 

Python - 函数进阶之装饰器