python装饰器由浅入深_由浅入深理解Python装饰器
前提知识:
1、Python里函数也是一种对象:
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!'
2、Python函数里面可以定义函数:
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
3、一个函数可以返回另外一个函数:
def getTalk(kind="shout"):
# We define functions on the fly
def shout(word="yes"):
return word.capitalize()+"!"
def whisper(word="yes") :
return word.lower()+"...";
# Then we return one of them
if kind == "shout":
# We don't use "()", we are not calling the function,
# we are returning the function object
return 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 :
# 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...这意味着可以把函数当做参数传递给其他函数:
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!
下面用几段代码来由浅入深地理解Python装饰器:
1、人工赋值的装饰器:
# 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 called
print "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 called
print "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
对
a_stand_alone_function重新赋值,这样每次调用a_stand_alone_function()的时候就自带装饰器了:
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
# And guess what? That’s EXACTLY what decorators do!
2、把上面这个例子用装饰器的语法重写如下:
@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
我们可以看到装饰器就是
another_stand_alone_function=my_shiny_new_decorator(another_stand_alone_function) 这句话简写
3、我们可以使用多个装饰器,他们之间是嵌套的顺序(从上到下):
def bread(func):
def wrapper():
print "''''''\>"
func()
print ""
return wrapper
def ingredients(func):
def wrapper():
print "#tomatoes#"
func()
print "~salad~"
return wrapper
def sandwich(food="--ham--"):
print food
sandwich()
#outputs: --ham--
sandwich = bread(ingredients(sandwich))
sandwich()
#outputs:
#''''''\>
# #tomatoes#
# --ham--
# ~salad~
#
用装饰器语法重写这个例子:
@bread
@ingredients
def sandwich(food="--ham--"):
print food
sandwich()
#outputs:
#''''''\>
# #tomatoes#
# --ham--
# ~salad~
#
装饰器顺序不同,程序运行的顺序也会不同,例如:
@ingredients
@bread
def strange_sandwich(food="--ham--"):
print food
strange_sandwich()
#outputs:
##tomatoes#
#''''''\>
# --ham--
#
# ~salad~
所以把握好多个装饰器运行的顺序是非常重要的。
(本文代码几个例子引用自stackoverflow上的一个回答:http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python/1594484#1594484)
python装饰器由浅入深_由浅入深理解Python装饰器相关推荐
- 如何用python写数值运算_如何理解Python的数值运算?
1 基本算术运算 1.1 使用规则 – Python解析器相当于一个简单的计算器 – Python解析器可以接受简单的算术表达式 – 运算符可以使加(+)减(-)乘(*)除(/) 1.2 实操理解 # ...
- python中的命名空间_深入理解Python中的命名空间和范围
Python中的命名空间和范围 在Python中,每个包.模块.类.函数和方法函数都拥有一个"名称空间",其中解析了变量名称.下面本篇文章就来带大家认识一下Python中的命名空间 ...
- python signal模块作用_如何理解python中信号Signal?
信号signal 是python进程间进行信号发送的一种机制,其原理是操作系统对进程的控制,是一种程序中断一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号. 那么singanl到底有什么用呢 ...
- python画爱心原理_如何理解python一行代码实现一个爱心字符画?
前言 python中有个很酷的效果,一行代码实现一个爱心字符,虽说是一行代码,但是理解起来还是比较难的,括号太多,并且使用了python的一些快捷小技巧.比如三元表达式,列表生成式,字符串拼接以及一个 ...
- 如何理解python中的函数_如何理解“python中函数是一等公民”?
python.js.scala等支持函数式编程的语言中,是如何体现"函数是一等公民(first class)"的?而在c/c++.java等静态语言中的一等公民又是什么?如何体现的 ...
- python逆向什么意思_如何理解python逆向切片
str = '0123456789' (推荐教程:python基础教程) 如上,我们有一个数值型字符串,接下来我们分别从正向和逆向两个维度截取数据.str[start:end:step] start表 ...
- python面向对象三大特性_深入理解Python面向对象的三大特性
在面向对象程序设计中,对象可以看做是数据(特性)以及由一系列可以存取.操作这些数据的方法所组成的集合.编写代码时,我们可以将所有功能都写在一个文件里,这样也是可行的,但是这样不利于代码的维护,你总不希 ...
- python中的常量_深入理解Python中的内置常量
前言 大家都知道Python内置的常量不多,只有6个,分别是True.False.None.NotImplemented.Ellipsis.__debug__.下面就来看看详细的介绍: 一. True ...
- python怎么装饰_如何理解python装饰器
如何理解装饰器 python 学习遇到的第一个难点是装饰器.装饰器的作用是不大规模改动代码的情况下,增加功能. 作用:为已经存在的对象添加额外的功能 特点:不需要对对象做任何的代码上的变动. 以一个例 ...
最新文章
- 为什么U-Net在医学图像上表现优越?
- Google Map API 学习六-设置infoWindow的长宽
- php 判定pc端與移動端
- php workerman demo,workerman-demo
- intellij 快捷键整理
- Linux文本编辑跳到指定行,Linux 命令每日一练:vi命令
- Indy9的IdFTP完全使用
- 实践录丨如何在鲲鹏服务器OpenEuler操作系统中快速部署OpenGauss数据库
- 软件测试——文档测试
- 普元EOS的项目部署
- 银行科技岗位 笔试 专业方向重点 + 面试一般问题
- AD9833数字信号发生器模块
- 自动化报表,标准化流程---“JSL”(JMP编程语言),与重复操作说拜拜
- 使用mono构建c#脚本运行环境
- 桑佛德大学计算机科学,美国桑佛德大学专业都有哪些?每个专业都有什么优势?一起来了解下吧?...
- Python安装word2vec
- latex 在线表格编辑器
- Node.js之npm ERR code EPERM npm ERR syscall open npm ERR
- 【运维心得】你不知道,运维也要写代码(3)
- SCA连载GDPR 数据处理案件分析 | 德国数据保护局vs德国学术机构,谁是数据控制者?