I love the decorator in Python!!!

Francesco Bochicchio bieffe62 at gmail.com
Fri Dec 9 07:00:06 EST 2011


On 8 Dic, 12:22, K.-Michael Aye <kmichael.... at gmail.com> wrote:
> On 2011-12-08 08:59:26 +0000, Thomas Rachel said:
>
>
>
> > Am 08.12.2011 08:18 schrieb 88888 Dihedral:
> >> I use the @ decorator to behave exactly like a c macro that
> >> does have fewer side effects.
>
> >> I am wondering is there other interesting methods to do the
> >> jobs in Python?
>
> > In combination with a generator, you can do many funny things.
>
> > For example, you can build up a string:
>
> > def mkstring(f):
> >      """Turns a string generator into a string,
> >      joining with ", ".
> >      """
> >      return ", ".join(f())
>
> > def create_answer():
> >      @mkstring
> >      def people():
> >          yield "Anna"
> >          yield "John"
> >          yield "Theo"
>
> >      return "The following people were here: " + people
>
> > Many other things are thinkable...
>
> > Thomas
>
> I am still perplexed about decorators though, am happily using Python
> for many years without them, but maybe i am missing something?
> For example in the above case, if I want the names attached to each
> other with a comma, why wouldn't I just create a function doing exactly
> this? Why would I first write a single name generator and then decorate
> it so that I never can get single names anymore (this is the case,
> isn't it? Once decorated, I can not get the original behaviour of the
> function anymore.
> So, above, why not
> def mkstring(mylist):
> with the same function declaration and then just call it with a list of
> names that I generate elsewhere in my program?
> I just can't identify the use-case for decorators, but as I said, maybe
> I am missing something.
>
> Michael

I had/have similar feelings. For instance,  this is something that I
tought useful, but then I never used in real code.
The idea was to find a way to automate this code pattern, which I do a
lot:

class SomeClass:
   def __init__(self, some, attribute, here ):
       self.some, self.attribute, self.here = some, attribute, here


In other words, I often define classes in which the constructor list
of arguments corresponds one-to-one to class attributes.
So I thought of this (it uses class decorators so it only works with
Python 3.x ) :


class FieldsDecorator:
    def __init__(self, *names):
        self.names = names

    def __call__(self, cls):
        def constructor(instance, **kwds):
            for n,v in kwds.items():
                if n in self.names:
                    setattr(instance, n, v)
                else: raise TypeError("%s is not a valid field" % s )
        setattr(cls, '__init__', constructor )
        return cls


@FieldsDecorator("uno", "due")
class Prova:
    pass

p = Prova(uno=12, due=9)
print (p.uno, p.due )


It works and it is nice, but I don't find it compelling enough to use
it. I keep assigning directly the attributes, which is more readable.

Decorators are really useful when you have lot of repetitive
boilercode that you _want_ to hide,  since it has little to do with
the problem logic and more to to with the technicalities of the
programming language or of some framework that you are using. It is
called "separating of concerns" I think, and is one of the principles
of Aspect-Oriented Programming (and  with decorators you can do some
nice AOP exercises ... ).

Ciao
---
FB




More information about the Python-list mailing list