简单上手Python中装饰器的使用

作者:Yi_Zhi_Yu 时间:2023-06-20 19:20:06 

Python的装饰器可以实现在代码运行期间修改函数的上下文, 即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作, 而函数本身并没有任何的改变。

这个看起来很复杂, 实际上应用到了我之前说过的闭包的概念, 仔细看一看, 其实并不复杂。

首先, 我们先定义一个函数, 这个函数可以输出我的个人昵称:


def my_name():
 print "Yi_Zhi_Yu"
my_name() # Yi_Zhi_Yu

那假如我需要在个人昵称输出前, 在输出我的个人uid呢, 当然, 要求是不改动现有的my_name函数, 这个时候就可以使用装饰器了

首先, 装饰器也是个函数, 其次, 他需要接受一个参数,该参数表示了要被装饰的函数(即my_name):


def my_info(func):
 def wrapper(*args, **params):
   print 218
   return func(*args, **params)
 return wrapper

然后与相应的被装饰函数关联起来的方法就是使用@my_info写在被装饰函数的前面


@my_info
def my_name():
 print "Yi_Zhi_Yu"

最后, 在执行my_name的时候, 就能既输出我的uid, 又能输出我的昵称了


my_name()
#218
#Yi_Zhi_Yu

在上面, 最让我们疑惑的是装饰器函数定义里面的wrapper函数, 装饰器本身返回的是wrapper函数的定义, 而wrapper中则定义了对被装饰函数(my_name)的调用, func表示的就是被装饰函数, 说白了, 装饰器只是把某个不得改动的函数(a)放到另一个函数(b)中, 在b里面调用a, 在调用前后就可以做所谓的看起来像装饰的工作了。
my_info的最终返回的wrapper函数的定义, 并不是执行结果,只有当wrapper真正执行的时候, 才会真正的执行my_name方法, 这就是闭包时所说的内容。
wrapper中的参数, 实际上则是传递给func(实际上是my_name)的参数

因为装饰器也是个函数, 那么装饰器自己的能不能有参数传递呢。可以, 不过需要定义一个更高阶的函数, 也就是外面还要套一层函数, 比如, 我还要输出我的自定义的一个信息,需要传递参数


def c_info(text):
 def my_info(func):
   def wrapper(*args, **params):
     print text
     print 218
     return func(*args, **params)
   return wrapper
 return my_info

#使用装饰器
@c_info("Tony")
def my_name():
 print "Yi_Zhi_Yu"

my_name()
#Tony
#218
#Yi_Zhi_Yu

与前面的那个装饰器相比, 仅仅是多了个外层, 内层也仅仅是增加了对外层传入参数(text)的调用

总而言之, Python在函数定义中支持了对oop思想中的装饰器的实现, 其本质也只是使用了闭包的思路, 延迟调用, 并在调用前后增加自己的其他实现内容

标签:Python,装饰器
0
投稿

猜你喜欢

  • python实现学生管理系统

    2022-12-18 02:42:22
  • Python之父谈Python的未来形式

    2022-02-05 11:10:42
  • Python实现生成随机日期字符串的方法示例

    2023-10-27 11:51:37
  • pycharm 复制代码出现空格的解决方式

    2023-08-27 12:36:37
  • Mootools 1.2教程(12)——用Drag.Move实现拖拽和拖放

    2008-12-05 12:29:00
  • Python装饰器与线程结合提高接口访问效率方法

    2021-07-16 11:28:32
  • 使用PyQt的QLabel组件实现选定目标框功能的方法示例

    2022-01-08 22:43:21
  • python多次绘制条形图的方法

    2021-07-22 09:36:45
  • Python正则表达式学习小例子

    2023-01-30 21:57:42
  • Django url,从一个页面调到另个页面的方法

    2021-08-08 03:51:51
  • php 读取文件头判断文件类型的实现代码

    2023-11-15 09:50:06
  • Go语言 go程释放操作(退出/销毁)

    2023-09-17 22:03:42
  • 如何在Unix系统环境下安装MySQL数据库

    2009-01-04 13:09:00
  • 用asp实现的代码批量修改程序

    2007-09-24 13:31:00
  • python实现简单flappy bird

    2022-08-03 12:06:33
  • python pandas loc 布尔索引示例说明

    2021-02-28 22:43:19
  • 如何为Access数据库表添加日期或时间戳

    2008-11-21 12:46:00
  • ASP提速技巧五则

    2008-03-20 13:20:00
  • mysql存储过程学习总结

    2011-07-04 12:03:53
  • jupyter notebook 重装教程

    2022-07-20 09:38:02
  • asp之家 网络编程 m.aspxhome.com