鱼C论坛

 找回密码
 立即注册
查看: 1494|回复: 0

[技术交流] 实用干货:如何理解装饰器(2)

[复制链接]
发表于 2017-3-30 20:20:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
函数引用

从以上两个例子我们可以得出,函数既然作为一个对象,因此:

1. 其可以被赋给其他变量

2. 其可以被定义在另外一个函数内

这也就是说,函数可以返回一个函数,看下面的例子:


  1. def getTalk(type="shout") :

  2.     # 我们定义另外一个函数
  3.     def shout(word="yes") :
  4.         return word.capitalize()+" !"

  5.     def whisper(word="yes") :
  6.         return word.lower()+"...";

  7.     # 然后我们返回其中一个
  8.     if type == "shout" :
  9.         # 我们没有使用(),因为我们不是在调用该函数
  10.         # 我们是在返回该函数
  11.         return shout
  12.     else :
  13.         return whisper

  14. # 然后怎么使用呢 ?

  15. # 把该函数赋予某个变量
  16. talk = getTalk()     

  17. # 这里你可以看到talk其实是一个函数对象:
  18. print talk
  19. #输出 : <function shout at 0xb7ea817c>

  20. # 该对象由函数返回的其中一个对象:
  21. print talk()

  22. # 或者你可以直接如下调用 :
  23. print getTalk("whisper")()
  24. #输出 : yes...
  25. 还有,既然可以返回一个函数,我们可以把它作为参数传递给函数:

  26. def doSomethingBefore(func) :
  27.     print "I do something before then I call the function you gave me"
  28.     print func()

  29. doSomethingBefore(scream)
  30. #输出 :
  31. #I do something before then I call the function you gave me
  32. #Yes !
复制代码


这里你已经足够能理解装饰器了,其他它可被视为封装器。也就是说,它能够让你在装饰前后执行代码而无须改变函数本身内容。

手工装饰

那么如何进行手动装饰呢?

  1. # 装饰器是一个函数,而其参数为另外一个函数
  2. def my_shiny_new_decorator(a_function_to_decorate) :

  3.     # 在内部定义了另外一个函数:一个封装器。
  4.     # 这个函数将原始函数进行封装,所以你可以在它之前或者之后执行一些代码
  5.     def the_wrapper_around_the_original_function() :

  6.         # 放一些你希望在真正函数执行前的一些代码
  7.         print "Before the function runs"

  8.         # 执行原始函数
  9.         a_function_to_decorate()

  10.         # 放一些你希望在原始函数执行后的一些代码
  11.         print "After the function runs"

  12.     #在此刻,"a_function_to_decrorate"还没有被执行,我们返回了创建的封装函数
  13.     #封装器包含了函数以及其前后执行的代码,其已经准备完毕
  14.     return the_wrapper_around_the_original_function

  15. # 现在想象下,你创建了一个你永远也不远再次接触的函数
  16. def a_stand_alone_function() :
  17.     print "I am a stand alone function, don't you dare modify me"

  18. a_stand_alone_function()
  19. #输出: I am a stand alone function, don't you dare modify me

  20. # 好了,你可以封装它实现行为的扩展。可以简单的把它丢给装饰器
  21. # 装饰器将动态地把它和你要的代码封装起来,并且返回一个新的可用的函数。
  22. a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
  23. a_stand_alone_function_decorated()
  24. #输出 :
  25. #Before the function runs
  26. #I am a stand alone function, don't you dare modify me
  27. #After the function runs
  28. 现在你也许要求当每次调用a_stand_alone_function时,实际调用却是a_stand_alone_function_decorated。实现也很简单,可以用my_shiny_new_decorator来给a_stand_alone_function重新赋值。

  29. a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
  30. a_stand_alone_function()
  31. #输出 :
  32. #Before the function runs
  33. #I am a stand alone function, don't you dare modify me
  34. #After the function runs

  35. # And guess what, that's EXACTLY what decorators do !
复制代码

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-30 18:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表