Python - 函数进阶之装饰器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = 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

 

 

以上是关于Python - 函数进阶之装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python之函数的进阶闭包装饰器

Python - 函数进阶之装饰器

Python 之 进阶学习

python进阶之装饰器之2.定义一个可接受参数的装饰器如何定义一个属性可由用户修改的装饰器定义一个能接受可选参数的装饰器

python函数四(装饰器进阶)

Python函数--装饰器进阶