当前位置: 首页 > 大杂烩 > 正文

Python中@修饰符的用法

From: http://www.python.org/dev/peps/pep-0318/

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

代码:

@dec2  
@dec1  
def func(arg1, arg2, ...):  
    pass  

等价于:

def func(arg1, arg2, ...):  
    pass  
func = dec2(dec1(func))  

示例1

def minus(f):
    print 'minus'
    f() 

def plus(f):
    print 'plus'
    f() 

def test(a):
    if a>3 :return plus
    else: return minus

@test(5)
def abc():
    print 'ok'

输出结果:

plus
ok

解析:解释器首先会解释@符号后面的代码,如果如上面的代码类似,那么test(5)将被执行,因为test参数5大于3,所以会返回一个函数指针plus(可以用C的这个名字来理解),plus将下一行的函数指针xxx当作参数传入,直到执行完成。最后结果将输出‘plus’和‘ok’。

def minus(f):
    print 'minus'
    f() 

@minus
def xxx():
    print 'ok'

因为本身已经是一个函数指针,所以会直接以xxx作为参数传入,结果会输出‘minus’和‘ok’

示例2:

def f1(arg):
    print "f1"
    rl = arg()
    print rl
    return rl + "f1"

@f1
def f2(arg = ""):
    print "f2"
    return arg + "f2r"

print "start"
print f2
#print f2("1") 出错
#print f1(None)

输出内容:

f1
f2
f2r
start
f2rf1

按ptyhon自带说明, 这里@符作符相当于 f1(f2()) 。但是从输出可以看出,这个运算其实在开始 import 时就已经在执行了,这也就是 f1 f2 f2r这几行会在 start 之前就出现的原因。

而当运行到代码时,其实 f2函数已经不存在了, f2 在这里已经变成一个字符串了, 这就是后面 #print f2(“1″) 会出错的原因,也就是说,实际上前面那些个 @ 操作符完成了这么一个操作:f2 = f1(f2()).f2已经被覆盖为 f1(f2) 的返回值了。运行时f2的结果已经固化,使用参数也不会重新计算,或者说根本无法使用参数。

实例3

def spamrun(fn):
    print "spam,spam,spam"
@spamrun
def useful(a,b):
    print a**2+b**2

结果:
spam,spam,spam

实例4

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)

结果:

spam,spam,spam

实例5

def addspam(fn):
    def new(*args):
    print "spam,spam,spam"
    return fn(*args)
    return new
@addspam
def useful(a,b):
    print a**2+b**2

useful(4,3)

结果:

spam,spam,spam
25

实例6

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)

结果:

My god!My god!My god!
25
My god!My god!My god!
25

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

My god!My god!My god!
My god!My god!My god!

要想使other函数能正常运行,必须加返回值,@decorator是一个statement,会将other函数当作参数传入来执行test方法

本文固定链接: http://sdnhub.cn/index.php/python-at/ | 软件定义网络SDN

该日志由 sdnhub 于2016年04月11日发表在 大杂烩 分类下, 通告目前不可用,你可以至底部留下评论。
原创文章转载请注明: Python中@修饰符的用法 | 软件定义网络SDN
关键字:

Python中@修饰符的用法:等您坐沙发呢!

发表评论

*

快捷键:Ctrl+Enter