6

I might seem stupid here. However, I was writing some python code, and this thing struck me. In python there are things called decorators which are denoted by @ and used "around" functions like:

class PlotABC(metaclass=ABCMeta):

  @property
  def figure(self):
    if self._figure is None: self.__create_figure()
    return self._figure

  @abstractmethod
  def _prepare_series(self):
    pass

I also know slivers of design patterns and I know there are patterns called decorators. Then once I thought, "Hey maybe the name similarity is not a bizarre coincidence."

I have read wiki: Decorator pattern and the great answer How to make a chain of function decorators? (almost whole).

It seems to me that python's decorator semantics are really powerful and can serve to implement the design pattern. As they allow to wrap around functions and methods. Though, I am still confused, since I am inexperienced with design patterns. I also do not know a language with such a dedicated mechanism for them.

Could someone experienced in python and design patterns say if the python semantics were purposely created to create decorator patterns? Is it something more, less, or does it mean something different?

And maybe throw some light how declaring a method abstract or a property is decorating it?

Community
  • 1
  • 1
luk32
  • 15,812
  • 38
  • 62
  • 1
    possible duplicate of [Whats the difference between Python decorators and Decorator Pattern?](http://stackoverflow.com/questions/8328824/whats-the-difference-between-python-decorators-and-decorator-pattern) – Marcin Jul 29 '13 at 15:32
  • @Marcin I swear I tried to search for it, lol. I also will vote to close mine as a duplicate. – luk32 Jul 30 '13 at 11:00

2 Answers2

9

No, it's not a bizarre coincidence, and no, python @decorators do not implement the GOF Decorator pattern.

The GOF (Gang of Four, so named after the four authors of the book "Design Patterns") decorator pattern adds "decorations" to change the behaviour of an object. It does this by creating "decorator" classes that can be applied to undecorated base classes.

Python decorators adds a "decoration" to a function or a class. These decorators are essentially functions that wrap or modify the function/class.

Both are similar in that you can re-use the decorator to add the same functionality several times, but the decorator pattern requires the decorators to be designed together with and for the classes that you can decorate.

Python decorators instead just do their work on any class of function.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • I have the feeling they can be used for the same thing ... and more. If you look at the question from my link, I seems to me, like they are used precisely for what a decorator pattern would be used. – luk32 Jul 29 '13 at 15:04
  • @luk32: I would say that your impression is largely incorrect. There is some overlap for class decorators and decorator patterns, absolutely, but not that much. That you probably *can* replace it completely doesn't mean it's a good idea. :-) – Lennart Regebro Jul 29 '13 at 15:06
  • So would you say, than the OP of the question http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python/1594484#1594484 and the 1,6k accepted answer abused it? Or I am not getting what a decoration is (very probable)? By the way, so far I got 2 answers which, I would say, are in high discourse both with the same number of up-votes. Maybe someone else will share their point of view. – luk32 Jul 29 '13 at 15:10
  • 1
    @luk32 That post isn't about decorator pattern. But then, I wouldn't worry about this issue very much, because you'll find that you rarely need to think about patterns in python. – Marcin Jul 29 '13 at 15:18
  • @Marcin I just imagine that in `c++` this would be very well implemented with decorators. Also, to be honest I didn't up to this point, especially seeing this question and answer. Maybe I got attracted to a bad example. – luk32 Jul 29 '13 at 15:23
  • @luk32 Well, in C++ you have a limited number of options, and a lot of stuff that we do with decorators or metaclasses, in C++ is most cleanly implemented with fiendishly clever templates. – Marcin Jul 29 '13 at 15:28
5

A "pattern" is a workaround for a missing language feature. "Decoration" is a term which pre-existed the Gang Of Four patterns book in programming - it has been used to describe any number of operations that involve adding some information or behaviour onto something else.

Strictly speaking, this isn't a way of implementing the decorator pattern, because it doesn't involve the creation of a class which composes other classes (except co-incidentally that that is one thing you can do with a decorator). It does, however, together with python's other features, render it largely obsolete.

In fact, I'd add that most "patterns" are a way of faking dynamic or reflective behaviour in C++, Java, and the like. You'll find very little excitement outside of those language communities. In Python decorators and metaclasses provide a way to encode all kinds of transformations - I'd guess that a majority of patterns which aren't trivial code be substantially replaced with specific decorators or metaclasses in Python.

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • I disagree that python decorators renders the decorator pattern obsolete. I think they solve different problems, although there may be some overlap. – Lennart Regebro Jul 29 '13 at 15:02
  • @LennartRegebro Well, I think that depends on whether you think all ways of accomplishing what a given patterns does is that pattern. Most patterns come down to ways of writing dynamic-ish code in an environment in which variables are statically typed, and multiple inheritance is problematic (or prohibited). – Marcin Jul 29 '13 at 15:16
  • Design Patterns are based on "A Pattern Language" and were originally applicable to buildings and urban planning, so if they could be applicable there I see no reason why they would not be applicable in Python or any other realm of designing things. Of course, the GoF patterns might not be a great fit for dynamic languages, but still patterns should be applicable to any designed thing. MVC for instance seems often used in Python apps. – charles ross Aug 15 '18 at 00:17
  • @charlesross Patterns for buildings are completely different. MVC as an architectural pattern is common, and indeed that is because there's no built in language feature that makes it invisible or unnecessary. – Marcin Aug 15 '18 at 13:49