3

I was playing with decorators, came up with following code.

def first(fn):
    def wrapper():
        print 'Before First'
        fn()
    return wrapper

def second(fn):
    def wrapper():
        print 'Before Second'
        fn()
    return wrapper

@second
@first
def fn():
    print 'The Original Function'

fn()

I get output as below

Before Second
Before First
The Original Function

I really don't get the order. I have read somewhere that decorator gets called in reverse order, I mean first should be called first and second should be called second. But the output suggests otherwise. What is happening here??

Ishan Bhatt
  • 9,287
  • 6
  • 23
  • 44
  • 1
    They are *applied* in reverse order, which causes their effects to be called in the order you placed them. – poke Dec 09 '15 at 07:54
  • I was confused at first as well because of the example that's linked here as being a duplicate of. But analyzing carefully made it clear. You have `fn = second(first(fn))` which you then call. So when you apply that chain, it represents the `wrapper` inner function from `second` function, since you last did `second(semething)` which returns `wrapper` inside. So `Before Second` prints first. Then `fn` represents `first(fn)` which is the `wrapper` from function `first` getting executed just now. So `Before First` prints. And then finally body of `fn` executes, so `The Original Function` prints. – Andrei-Niculae Petre Apr 27 '17 at 18:05

1 Answers1

2

You start from original function. Then go up. Imagine it like: second(first(fn)).

See more in this answer

Community
  • 1
  • 1
DAKZH
  • 243
  • 2
  • 12