3

My question revolves around the intended lifetime of an implemented Python decorator. From realpython.org it says:

''By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.''

To me, it seems like decorators quite frequently are used in examples online to temporarily modify or extend a python function, such as in the html formatting examples.

Example:

Let's say that I work at a web development company and at the top of all of my webpages I call this Python function page_welcome().

def page_welcome():
    return "Welcome to XYZ's company webpage!"

Now, some developer joins the company and decides we should make this stand out more by modifying the function with some bold and italics.

def makebold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped    

def makeitalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped    

@makebold
@makeitalic
def page_welcome():
    return "Welcome to XYZ's company webpage!"

If we decide this change is to be permanent, are decorators the best way of leaving in this permanent modification?

Note: The example above is the decorator example from this link (modified slightly): How to make a chain of function decorators?

Community
  • 1
  • 1
Scott Skiles
  • 3,647
  • 6
  • 40
  • 64
  • 1
    Why do you think they're temporary? Do you see any examples where they're somehow removed? You could put the bold and italic in the function, but then it has multiple concerns and limited reuse. – jonrsharpe Nov 17 '16 at 08:09
  • 2
    Decorators are not temporary. You usually define a decorator and apply it to many functions, hence they are a way to make the code DRYer (i.e. with less repetitions). For example in frameworks like Django you have a decorator like `login_require` that you can attach to functions that represent web pages that can only be seen by logged in users, and the decorator makes it so that people not logged in are first redirected to the login page. Not using a decorator you'd have to put a few lines at the beginning of all these functions to manually check the user and redirect him... – Bakuriu Nov 17 '16 at 08:12
  • 3
    I do not understand your purpose. If you decide to change the string permanently, why not just hard code into your string? – Kir Chou Nov 17 '16 at 08:12
  • @all, I don't see any examples of them being removed, but that is just how some of the examples seemed to come off. I suppose the syntactic sugar, while aiding in the DRY philosophy, seems fragile to me at first glance. That is, behavior is removed just as easily as it is added, and to the uninitiated it seems like this could happen accidentally quite easily. – Scott Skiles Nov 17 '16 at 08:58

1 Answers1

3

Decorators' main purpose is not for temporary modification of function behaviour. The word "temporarily" is odd here. It is better to think about them as decomposition of responsibilities and code reuse. They are mostly used to add some behaviour which is not uniquely bound to decorating function and can be used for other functions too. One good example is the @memoized decorator, which remembers the value computed by the decorated function (which may take a lot of time to compute) and next time returns the value immediately. Such a decorator can be reused many times and, besides that, it makes core much more readable: instead of bloating your function with memoization code you add a single line which clearly states what actually happens.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Alexey Guseynov
  • 5,116
  • 1
  • 19
  • 29
  • Coming back to this, and learning a lot since I posted this, it would be good to edit this answer to include a note on how a decorator is a design pattern in and of itself, and is not limited to Python. – Scott Skiles Jul 06 '18 at 13:33