使用@符号进行装饰和使用python进行装饰之间的区别

时间:2014-03-20 09:36:48

标签: python recursion decorator

请考虑以下代码 这里我没有使用@符号进行装饰

import math

def isOddMy(func):
    def innerOdd(x):
        y = func(x)
        if math.fmod(y, 2) == 0 :
            return 0
        else:
            if y is not None:
                return y
            else:
                return 0
    return innerOdd

#@isOddMy
def fib(n):
    #print n,
    if n == 0 :
        return 0
    elif n == 1 :
        return 1
    else:
        return fib(n-2) + fib(n-1)


def main():
    #oddFibi = isOdd(fib)
    #print [i for i in oddFibi(100)]
    for i in range(1,10):
        print fib(i),

    print
    fib1 = isOddMy(fib)
    for i in range(1,10):
        print fib1(i),

if __name__ == '__main__':
    main()

,结果是

1 1 2 3 5 8 13 21 34

1 1 0 3 5 0 13 21 0

而在下面我使用了@符号但结果是 1 1 0 1 1 0 1 1 0

为什么会这样?

import math

def isOddMy(func):
    def innerOdd(x):
        y = func(x)
        if math.fmod(y, 2) == 0 :
            return 0
        else:
            if y is not None:
                return y
            else:
                return 0
    return innerOdd

@isOddMy
def fib(n):
    #print n,
    if n == 0 :
        return 0
    elif n == 1 :
        return 1
    else:
        return fib(n-2) + fib(n-1)


def main():
    #oddFibi = isOdd(fib)
    #print [i for i in oddFibi(100)]
    for i in range(1,10):
        print fib(i),

    '''print
    fib1 = isOddMy(fib)
    for i in range(1,10):
        print fib1(i),'''

if __name__ == '__main__':
    main()

感谢。

1 个答案:

答案 0 :(得分:3)

差异可能与递归调用有关。当fib调用fib时,会在模块范围中查找该名称。如果使用@装饰器语法,则会找到名称为fib的修饰函数。如果您只是执行fib1 = isOddMy(fib),则会找到名为fib的未修饰函数。