Going the PL/1 way

Christian Tismer tismer at stackless.com
Mon Aug 9 12:09:52 CEST 2004

Harald Massa wrote:

> Miklós,
>>>I do not understand at all what's that decorators thingy, but I know
>>>that girls often put some deco into flats and it really looks cosy
>>>after, so I assume that decorators are not on the dark side of the
>>The rest of the novelties in v2.4 are more or less fine with me, too.
>>But IMHO decorators are exactly Dark Code Wader stuff. Basically it's
>>about self-modifying code.

Ooh, this is truely too much fear. Decorators are about
modification of how code is understood, but not modification.
[ If it were so, then I'd be probably much more interested :-) ]

> I honestly ask that someone could explain to the less enlightened like me 
> what this decorator thingy really is. What does it make a correct step on 
> the path to enlightenment?

Here a very short and very incomplete explainment of what
a decorator is. FOr a more complete explanation, please
refer to the PEP, or even wade through python-dev.
I also just give one simple example, there are lots of
other uses for decorators.
But since probably more than 95 percent of Python code will
not need decorators in the near future, just one example
should be enough to just don't let you worry about what
the Voodoo is.

Something many Python programmers even don't know about are
class methods and static methods.

A static method is simply a method which is defined in a class,
but that does not operate on self. The self variable is not
supplied. A static method is not supposed to be a method of an
instance. It is just sitting in a class for convenience, but
behaves like an ordinary function.

There is a more advanced concept: a class method. Instead of self
or nothing, it always receives the class as first parameter.
But please read the docstring of the classmethod function.
We will stick with the simple static method, here.

Until Python 2.3, it was necessary to "declare" a static method
by calling the function staticmethod on it.

Sample code:

class MyClass(object):

     def func(arg1, arg2):
         return arg1 + arg2

     func = classmethod(func)

What can you see here?
The "def func" lacks a self parameter. You want to call it
with the two parameters arg1 and arg2, but without the
extra line
     func = classmethod(func)

you would get this result:
Trying to call func via the class gives you

 >>> MyClass.func(2, 3)
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
TypeError: unbound method func() must be called with MyClass instance as 
first argument (got int instance instead)

Trying to call func via an instance also doesn't work:

 >>> inst = MyClass()
 >>> inst.func(2, 3)
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
TypeError: func() takes exactly 2 arguments (3 given)

Now, with the mentioned extra line, the function object is
modified in a way that it understands that it is an ordinary
function, and it works in both cases:

 >>> class MyClass(object):
... 	def func(arg1, arg2):
... 		return arg1 + arg2
... 	func=staticmethod(func)
 >>> MyClass.func(2, 3)
 >>> inst = MyClass()
 >>> inst.func(2, 3)

--- now finally on the decorator issue ---

What you have see is, that staticmethod has to be called *after*
the function is defined. The modified function is assigned to
the class as a post process.
For very long functions, this can become cumbersome.
Not only that you have to type the function name three times,
you also have to scroll through the full function definition,
possibly even through the rest of the whole class definition,
to see whther the function is modified somehow.

One of the purposes of decorators is now to overcome this
problem, and to annotate the function earlier than at its end.
There are many proposals how to do this, also with extended
functionality. But I'll reduce the example to the currently
proposed syntax:

class MyClass(object):


     def func(arg1, arg2):
         return arg1 + arg2

This is the basic idea what a decorator does:
Make modifiers like classmethod into a prefix
of a function.

I know this description is incomplete, but I beg those who
know better _not_ to respond and prove their knowledge.
I wanted to give a simple idea. Corrections are welcome, of course.
Everything else is documented in PEP318.

ciao - chris

Christian Tismer             :^)   <mailto:tismer at stackless.com>
Mission Impossible 5oftware  :     Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a     :    *Starship* http://starship.python.net/
14109 Berlin                 :     PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34  home +49 30 802 86 56  mobile +49 173 24 18 776
PGP 0x57F3BF04       9064 F4E1 D754 C2FF 1619  305B C09C 5A3B 57F3 BF04
      whom do you want to sponsor today?   http://www.stackless.com/

More information about the Python-list mailing list