分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net

Decorator Basics

Python’s functions are objects

To understand decorators, you must first understand that functions are objects in Python. This has important consequences. Let’s see why with a simple example :

def shout(word="yes"):return word.capitalize()+"!"print(shout())
# outputs : 'Yes!'# As an object, you can assign the function to a variable like any other object
scream = shout# Notice we don't use parentheses: we are not calling the function,
# we are putting the function "shout" into the variable "scream".
# It means you can then call "shout" from "scream":print(scream())
# outputs : 'Yes!'# More than that, it means you can remove the old name 'shout',
# and the function will still be accessible from 'scream'del shout
try:print(shout())
except NameError, e:print(e)#outputs: "name 'shout' is not defined"print(scream())
# outputs: 'Yes!'

Keep this in mind. We’ll circle back to it shortly.

Another interesting property of Python functions is they can be defined inside another function!

def talk():# You can define a function on the fly in "talk" ...def whisper(word="yes"):return word.lower()+"..."# ... and use it right away!print(whisper())# You call "talk", that defines "whisper" EVERY TIME you call it, then
# "whisper" is called in "talk".
talk()
# outputs:
# "yes..."# But "whisper" DOES NOT EXIST outside "talk":try:print(whisper())
except NameError, e:print(e)#outputs : "name 'whisper' is not defined"*#Python's functions are objects

Functions references

Okay, still here? Now the fun part...

You’ve seen that functions are objects. Therefore, functions:

  • can be assigned to a variable
  • can be defined in another function

That means that a function can return another function.

def getTalk(kind="shout"):# We define functions on the flydef shout(word="yes"):return word.capitalize()+"!"def whisper(word="yes") :return word.lower()+"...";# Then we return one of themif kind == "shout":# We don't use "()", we are not calling the function,# we are returning the function objectreturn shout  else:return whisper# How do you use this strange beast?# Get the function and assign it to a variable
talk = getTalk()      # You can see that "talk" is here a function object:
print(talk)
#outputs : <function shout at 0xb7ea817c># The object is the one returned by the function:
print(talk())
#outputs : Yes!# And you can even use it directly if you feel wild:
print(getTalk("whisper")())
#outputs : yes...

There’s more!

If you can return a function, you can pass one as a parameter:

def doSomethingBefore(func): print("I do something before then I call the function you gave me")print(func())doSomethingBefore(scream)
#outputs:
#I do something before then I call the function you gave me
#Yes!

Well, you just have everything needed to understand decorators. You see, decorators are “wrappers”, which means that they let you execute code before and after the function they decorate without modifying the function itself.

Handcrafted decorators

How you’d do it manually:

# A decorator is a function that expects ANOTHER function as parameter
def my_shiny_new_decorator(a_function_to_decorate):# Inside, the decorator defines a function on the fly: the wrapper.# This function is going to be wrapped around the original function# so it can execute code before and after it.def the_wrapper_around_the_original_function():# Put here the code you want to be executed BEFORE the original function is calledprint("Before the function runs")# Call the function here (using parentheses)a_function_to_decorate()# Put here the code you want to be executed AFTER the original function is calledprint("After the function runs")# At this point, "a_function_to_decorate" HAS NEVER BEEN EXECUTED.# We return the wrapper function we have just created.# The wrapper contains the function and the code to execute before and after. It’s ready to use!return the_wrapper_around_the_original_function# Now imagine you create a function you don't want to ever touch again.
def a_stand_alone_function():print("I am a stand alone function, don't you dare modify me")a_stand_alone_function()
#outputs: I am a stand alone function, don't you dare modify me# Well, you can decorate it to extend its behavior.
# Just pass it to the decorator, it will wrap it dynamically in
# any code you want and return you a new function ready to be used:a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function_decorated()
#outputs:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs

Now, you probably want that every time you call a_stand_alone_functiona_stand_alone_function_decorated is called instead. That’s easy, just overwrite a_stand_alone_function with the function returned by my_shiny_new_decorator:

a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function)
a_stand_alone_function()
#outputs:
#Before the function runs
#I am a stand alone function, don't you dare modify me
#After the function runs# That’s EXACTLY what decorators do!

Decorators demystified

The previous example, using the decorator syntax:

@my_shiny_new_decorator
def another_stand_alone_function():print("Leave me alone")another_stand_alone_function()
#outputs:
#Before the function runs
#Leave me alone
#After the function runs

Yes, that’s all, it’s that simple. @decorator is just a shortcut to:

another_stand_alone_function = my_shiny_new_decorator(another_stand_alone_function)

Decorators are just a pythonic variant of the decorator design pattern. There are several classic design patterns embedded in Python to ease development (like iterators).

Of course, you can accumulate decorators:

def bread(func):def wrapper():print("</''''''\>")func()print("<\______/>")return wrapperdef ingredients(func):def wrapper():print("#tomatoes#")func()print("~salad~")return wrapperdef sandwich(food="--ham--"):print(food)sandwich()
#outputs: --ham--
sandwich = bread(ingredients(sandwich))
sandwich()
#outputs:
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>

Using the Python decorator syntax:

@bread
@ingredients
def sandwich(food="--ham--"):print(food)sandwich()
#outputs:
#</''''''\>
# #tomatoes#
# --ham--
# ~salad~
#<\______/>

The order you set the decorators MATTERS:

@ingredients
@bread
def strange_sandwich(food="--ham--"):print(food)strange_sandwich()
#outputs:
##tomatoes#
#</''''''\>
# --ham--
#<\______/>
# ~salad~

Python - How to make a chain of function decorators?相关推荐

  1. python 重载的实现(single-dispatch generic function)

    DAY 11. python 重载 函数重载是指允许定义参数数量或类型不同的同名函数,程序在运行时会根据所传递的参数类型选择应该调用的函数 ,但在默认情况下,python是不支持函数重载的,定义同名函 ...

  2. 【Python函数式编程】——偏函数(Partial function)

    Python函数式编程--偏函数   Python的 functools 模块提供了很多有用的功能,其中一个就是偏函数(Partial function).要注意,这里的偏函数和数学意义上的偏函数不一 ...

  3. python functiontype_Python多处理PicklingError:无法pickletype'function'

    这是一张list of what can be pickled.特别是,函数只有在模块的顶层定义时才是可选择的. 这段代码:import multiprocessing as mp class Foo ...

  4. python fabric 部署falcon tcp closewait monitor function

    @task @roles('userdefine') def falcon_plugin_ss_expand():# 下载软件run("""yum install -y ...

  5. UserWarning: Label not :NUMBER: is present in all training examples

    UserWarning: Label not :NUMBER: is present in all training examples 目录 UserWarning: Label not :NUMBE ...

  6. 为什么离不开 Stackoverflow

    作为一名程序员,如果没有听过 Stackoverflow,那么你最好去面壁思过一下.程序员最需要阅读的一本编程书籍(其实编程书留下这本就够了!): 那些还没有读过这本书的程序员,是时候买一本了.如果还 ...

  7. python调用mysql中的自定义function并且返回结果

    首先在Mysql中创立一个叫ForeignKeyTest的function,链接如下: https://blog.csdn.net/appleyuchi/article/details/7945291 ...

  8. Python Module — asyncio 协程并发

    目录 文章目录 目录 Python Co-routines Asyncio Module Event Loop Async 与 Await async def async for async with ...

  9. python必背内容-【经验分享】学Python必背的初级单词

    今天给大家分享一些学习Python必须认识的英文单词,同时也是学习编程都必须会的单词,新手赶快学起来! application 应用程式 应用.应用程序 application framework 应 ...

  10. python基础单词-学Python必背的初级单词,快来看看学吧

    今天给大家分享一些学习Python必须认识的英文单词,同时也是学习编程都必须会的单词,新手赶快学起来!有点长耐心看完. application 应用程式 应用.应用程序 application fra ...

最新文章

  1. java指针操作符_rxjava 操作符大全
  2. 怎么找出电脑里隐藏的流氓软件_9成人都不知道的秘密!那些隐藏在你电脑里的“大象”!...
  3. 二级计算机excel以宏保存,Excel宏保存
  4. 使用touch更新文件的时间
  5. 前端:JS/32/form对象(表单)(form对象的属性,方法和事件),受返回值影响的两个事件(onclick事件,onsubmit事件),获取表单的元素对象的三种方式,表单的提交和验证方法总结
  6. js判断是否为ie浏览器
  7. 怎么将后缀为.opt,.frm,.myd,.myi文件还原或者是导入mySQL中
  8. JavaScript回顾与学习——运算符
  9. 关于EasyRecovery的一些高级设置
  10. 数据包接收系列 — NAPI的原理和实现
  11. Python执行Linux系统命令方法
  12. paip.python错误解决23
  13. Eclipse最新SVN(4.2.x )插件subclipse安装方法
  14. MAX232(MAX3232)电平转换芯片的工作原理
  15. UNIX环境高级编程(第2版)- 第1~10章
  16. 将一个对象转换成数组
  17. IPhone手机打开EPUB文件教程
  18. 关于QQ号的分发管理机制的基本方案的设计猜想和分析讨论
  19. Linux重启后硬盘挂载失效问题解决
  20. 图解angr中两种CFG的区别

热门文章

  1. PyQt5简易本地视频播放器
  2. 数理统计之方差分析及python实现
  3. Oracle-select...into...from语句的使用
  4. Python 散点图的数据分析
  5. VC707开发板的IIC控制
  6. 短视频剪辑入门技巧,简单却重要
  7. 如何卸载CAD?怎么把CAD彻底卸载干净重新安装的方法
  8. The following method did not exist:com.google.gson.GsonBuilder.setLenient()
  9. 【BDTC 2016】专访中兴飞流吕阿斌、郑龙:Yita,基于数据流的大数据计算引擎...
  10. 没落的移动端原生开发