python中@的用法

@修饰符作为python语法中的一个修饰符,在修饰函数上有很多不可替代的特性,常应用与staticmethod和classmethod的声明中。

1.经典的old style风的方法转换

def enhanced(meth):
    def new(self, y):
        print "I am enhanced"
        return meth(self, y)
    return new
class C:
    def bar(self, x):
        print "some method says:", x
    bar = enhanced(bar)

通过enhanced我们把bar升级成了一个new函数。

2.然而现在我们仅仅只需要通过一个@修饰符就能完成这种转换:

class C:
    @classmethod
    def foo(cls, y):
        print "classmethod", cls, y
    @enhanced
    def bar(self, x):
        print "some method says:", x

这里的bar也像1那样“enhance“成了一个new函数。而上面的foo函数我们也可以理解成它被“升级“成了一个类函数。

3.那么它具体是怎么实现的呢?

@synchronized
@logging
def myfunc(arg1, arg2, ...):
    # ...do something
# decorators are equivalent to ending with:
#    myfunc = synchronized(logging(myfunc))
# Nested in that declaration order

这里我用了一个修饰链(事实上就是函数的递归调用),修饰符@的作用等价于
myfunc = synchronized(logging(myfunc)),也就是说我们把myfunc作为一个参数传递给了修饰符中的函数并根据它的返回值给myfunc赋值。

我们举一个例子:

def addspam(fn):
    def new(*args):
        print ("spam, spam, spam",*args)
        return fn(*args)
    return new

@addspam
def useful(a, b):
    print (a**2 + b**2)

useful(3,4)

它的输出:

spam, spam, spam 3 4
25

这里我解释一下它的输出:

首先当执行到@addspam时就发生了我如上所说的
useful=addspam( useful(3,4) )

看到addspam函数的定义,如果你明白了我1中讲述的函数转换你就能很快明白
addspam函数内定义了一个新函数new完成转换

这个new函数很简单:
我们加入了一个简单的输出print (“spam, spam, spam”,*args),然后就把这个函数原样返回了return fn(*args)。(其中fn就是useful的函数调用,*args就是useful的参数。)

然后我们将这个new函数返回就完成了这个”修饰符函数”。

最后当我们实际调用useful(3,4)时,根据我们刚刚的返回值useful=addspam( useful(3,4) ),useful**其实是没用任何的变化的**,所以当执行useful的时候就输出25,

因为@修饰符在声明时已经完成了一次useful的转换,我们之后就不要再在意addspam的定义啦~
参考来自https://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值