1

I'm starting studying decorators and I already hit an obstacle. First here is my code.

 def deco (f):

    def coucou():
        print("this is function{}".format(f))
        return f()
    return coucou

@deco
def salut():
    print("salut")


def hi():
    return salut()

I will try to explain my problem as well as I can with my bad English. If I understand it this is how things should happen: I execute my hi() function which returns salut() and because salut is modified by the decorator coucou will be executed and coucou returns ....... salut(), what i mean is that I expect an infinite loop but that doesn't happen and I don't understand why. Can anyone explain practically how decorators work?

Ondrej K.
  • 8,841
  • 11
  • 24
  • 39
  • https://realpython.com/primer-on-python-decorators/ This may help in understanding how decorators work – Pro Q Jan 19 '19 at 00:20
  • You may also want to have a look at the documentation: [PEP-318](https://www.python.org/dev/peps/pep-0318/#current-implementation-history) and [PEP-3129](https://www.python.org/dev/peps/pep-3129/#implementation). – Ondrej K. Jan 19 '19 at 00:29

1 Answers1

2

The f in coucou is the undecorated (original) version of salut.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • yeah but why and how? again if i got it, the decorator modify the function in its definition and makes it point permanently to the function returned by the decorator, am i wrong? – Newgate Ace Jan 19 '19 at 00:13
  • 1
    @NewgateAce it *doesn't* modify the original function. It creates a new function, and returns a new function. So the *global name* `salut` now refers to the function returned by the decorator, i.e. `coucou`, but `coucou`'s *local name* `f`, which is a free variable closed over by `coucou`, still refers to the original function – juanpa.arrivillaga Jan 19 '19 at 00:16
  • @NewgateAce in other words, there is nothing magical about the decorator syntax. It is equivalent to `def my_function(): ...; my_func = deco(my_func)` – juanpa.arrivillaga Jan 19 '19 at 00:24
  • @juanpa.arrivillaga i see now, f = deco(f) makes it clearer for me. thanks for your reply. – Newgate Ace Jan 19 '19 at 00:30
  • @juanpa.arrivillaga what im about to say might be stupid, but when i print "salut" and "deco(salut)", they dont have the same reference ... – Newgate Ace Jan 19 '19 at 00:46
  • Um, because `deco(salut)` will *create a new object each time it is called*, but what, *exactly* are you doing? – juanpa.arrivillaga Jan 19 '19 at 00:49