本文接下来的装饰器部分内容参考自
https://taizilongxu.gitbooks.io/stackoverflow-about-python/content/3/README.html
部分内容加入了自己的理解,欢迎批评指正!!!
1. Python中的函数都是对象
比如:
def shout(word="yes"):
return word.capitalize()+"!"
print(shout())
# 输出 : 'Yes!'
作为一个对象,你可以把它赋值给任何变量
scream = shout
print(scream())
# 输出 : 'Yes!'
我们没有加括号,我们并不是调用这个函数,我们只是把函数"shout"放在了变量"scream"里.也就是说我们可以通过"scream"调用"shout":
可以删除旧名"shout",而且"scream"依然指向函数
del shout try: print(shout()) except NameError as e: print(e) print(scream())
输出:
#name 'shout' is not defined
#Yes!
关键点:可以在一个函数里定义另一个函数
talk()
# 输出:
# "yes..."
# 每次调用"talk"时都会定义一次"whisper",然后"talk"会调用"whisper"
try: print(whisper()) except NameError as e: print(e)
# 但是在"talk"外"whisper"是不存在的:
#输出 : "name 'whisper' is not defined"*
2. 函数引用
函数就是对象.因此,对象:
- 可以赋值给一个变量
- 可以在其他函数里定义
这就意味着函数可以返回另一个函数.
def getTalk(kind="shout"):
#在函数里定义一个函数
def shout(word="yes"):
return word.capitalize()+"!"
def whisper(word="yes"):
return word.lower()+"..."
#返回一个函数
if kind == "shout":
return shout
# 这里不用"()",我们不是要调用函数
# 只是返回函数对象
else:
return whisper
talk = getTalk()
print talk
输出 : <function shout at0xb7ea817c>,即函数返回的是对象
print talk()
# 输出 : Yes!
上述等价于print getTalk()()
既然可以return一个函数, 也可以在把函数作为参数传递:
def shout(word="yes"):
return word.capitalize()+"!"
scream = shout
def doSomethingBefore(func):
print("I do something before then I call the function you gave me")
print(func())
doSomethingBefore(scream)
执行
doSomethingBefore(scream)
输出:
I do something before then I call the function you gave me
Yes!
上述即为学习装饰器的基本知识.装饰器就是"wrappers",它可以让你在你装饰函数之前或之后执行程序,而不用修改函数本身.