python中@的作用

  在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"

@funa
@funb
def func(c):
print "funC"


if __name__ == "__main__":
func

  最后得到的结果是:

1
2
funB  
funA

  通过结果我们可以认为:return funa(funb(func)),也即第一个函数修饰符开始,自下而上做参数传递,这样实际是使用了约定的函数修饰符达到函数嵌套的目的。记得没错Java中SSH也有这样的用法哦。
其他例子:
1.

1
2
3
4
5
6
7
8
9
10
def spamrun(fn):
def sayspam(*args):
print "spam,spam,spam"
return sayspam

@spamrun
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
6
def spamrun(fn):
print "spam,spam,spam"

@spamrun
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
11
def decorator(fn):
def test(*args):
print "My god!"*3
return fn(*args)
return test
@decorator
def other(a,b):
print a**2+b**2
if __name__=="__main__":
other(4,3)
other(3,4)

结果:

1
2
3
4
My god!My god!My god!
25
My god!My god!My god!
25

注释掉//return fn(*args),结果:

1
2
My god!My god!My god!
My god!My god!My god!

  解释:要想使other函数能正常运行(即调用other函数并将其参数继续往下传),必须加返回值,@decorator是一个statement,会将other函数当作参数传入来执行test方法。

  总结:’@’符号用作函数修饰符是python2.4新增加的功能,修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说@A def f(): 是非法的。 只可以在模块或类定义层内对函数进行修饰,不允许修修饰一个类。一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。

  感悟:@的作用有点像代理模式,即@functionName修饰的函数是由functionName函数管理。