在python2.4以上的函数中经常看到函数定义上一行有@functionName的修饰,注意下这个语法细节,有点像c语言中带参数的宏操作,当解释器读到这样的修饰之后,会先解析@后的内容,直接把@下一行的函数或者类作为@后边的函数的参数,然后将返回值赋值给下一行修饰的函数对象。
例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# !/usr/bin/env python
# -*- coding: utf-8 -*-
def funa(a):
print "funa"
def funb(b):
print "funB"
def func(c):
print "funC"
if __name__ == "__main__":
func
最后得到的结果是:1
2funB
funA
通过结果我们可以认为:return funa(funb(func)),也即第一个函数修饰符开始,自下而上做参数传递,这样实际是使用了约定的函数修饰符达到函数嵌套的目的。记得没错Java中SSH也有这样的用法哦。
其他例子:
1.1
2
3
4
5
6
7
8
9
10def spamrun(fn):
def sayspam(*args):
print "spam,spam,spam"
return sayspam
def useful(a,b):
print a**2+b**2
useful(3,4)
结果:1
spam,spam,spam
解释:只是将函数useful传递给spamrun,并没用使用,因此最终返回的是spamrun函数的结果。
2.1
2
3
4
5
6def spamrun(fn):
print "spam,spam,spam"
def useful(a,b):
print a**2+b**2
结果:1
spam,spam,spam
解释:只是将函数useful传递给spamrun,并没用使用,因此最终返回的是spamrun函数的结果。
3.1
2
3
4
5
6
7
8
9
10
11def decorator(fn):
def test(*args):
print "My god!"*3
return fn(*args)
return test
def other(a,b):
print a**2+b**2
if __name__=="__main__":
other(4,3)
other(3,4)
结果:1
2
3
4My god!My god!My god!
25
My god!My god!My god!
25
注释掉//return fn(*args),结果:1
2My god!My god!My god!
My god!My god!My god!
解释:要想使other函数能正常运行(即调用other函数并将其参数继续往下传),必须加返回值,@decorator是一个statement,会将other函数当作参数传入来执行test方法。
总结:’@’符号用作函数修饰符是python2.4新增加的功能,修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说@A def f(): 是非法的。 只可以在模块或类定义层内对函数进行修饰,不允许修修饰一个类。一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。
感悟:@的作用有点像代理模式,即@functionName修饰的函数是由functionName函数管理。