1

Consider the following code Here I have not used the @ symbol for decoration

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()

and the result is

1 1 2 3 5 8 13 21 34

1 1 0 3 5 0 13 21 0

whereas below i have used @ symbol but the result is 1 1 0 1 1 0 1 1 0

Why is this so??

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()

Thanks.

sshashank124
  • 31,495
  • 9
  • 67
  • 76
muru
  • 111
  • 1
  • 1
  • 10
  • 2
    I don't know but i'm a bit lazy to write for someone who write 'Why' as 'Y' ^_^ – aIKid Mar 20 '14 at 09:37
  • Well, first you need to understand what a decorator is. Please read [this article](http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/) and [this answer](http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python) – aIKid Mar 20 '14 at 09:39
  • On second thought, the extra angle of this being a recursive function makes it harder to justify this as a dupe; retracted again. – Martijn Pieters Mar 20 '14 at 09:53

1 Answers1

3

The difference is probably to do with the recursive call. When fib calls fib, that name is looked up in module scope. If you use the @ decorator syntax, the decorated function is found with name fib. If you just do fib1 = isOddMy(fib), the undecorated function is found with name fib.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • thanks you are correct since i checked with a non recursive fib() function and the @ symbol works there.but are there any work arounds.. – muru Mar 20 '14 at 09:49
  • @muru Any workarounds for what exactly? It is not clear what you want to do. – Janne Karila Mar 20 '14 at 10:54
  • @Janne I meant that using the @ symbol for the decorator to the recursive function and more importantly getting the result like the other program(the one without the @ symbol used for decorator) – muru Mar 20 '14 at 11:00
  • @muru If one approach gives you the desired result, I would say that it *is* a workaround. – Janne Karila Mar 20 '14 at 11:27
  • @JanneKarila i wish i have a deeper understanding of the inner workings – muru Mar 20 '14 at 11:51