Decorator metaclass

Carl Banks pavlovevidence at gmail.com
Fri May 23 15:24:41 EDT 2008


On May 23, 11:42 am, Thomas Karolski <Thomas.Karol... at googlemail.com>
wrote:

> > You will note that Decorator does not define __init__.  In fact,
> > object.__init__ will be called, which does nothing.  If you think that
> > all classes with DecoratorType as their metaclass will be a direct
> > subclass of Decorator, you can get away with not calling
> > Decorator.__init__ at all.
>
> Now, inside my new version, I have a class which inherits from both
> Decorator and Window, out of which the __init__ for Decorator is not
> called. Does this prove to be a problem?

It sounds like it could create infinite recursion.  If your decorated
class inherits from Decorator, it should also get the DecorateType
metaclass, which should recursively try to create its own decorated
class, ad infinitum.  Unless I misunderstand what you meant.


> > Probably the best piece of advice is "Don't try to use Decorator
> > pattern".  :)
>
> Well, I decided on the decorator pattern, because I want to be able to
> change the behavior of classes during run-time. I did not really find
> any other pattern which would let me do that.


Ah.

Well it is possible to do that in Python. though there's probably not
an official design pattern for it (but then design patterns grew up
around less flexible languages, partially as a way to cope with their
lack of flexibility).  Here are a couple things to think about:

If you'd like to change the behavior of individual instances of a
class, you can assign functions to individual instances which act just
like methods.  (Warning: this does not work with operators.)

Here is an example:

    class A(object):
        def say_hello(self):
            print "hello, world"

    a = A()

    def custom_hello():
        print "hello, my name is Inigo Montoya"

    a.say_hello = custom_hello


If you'd like to change the behavior of all instances of the class,
then you can assign a new method directly to the class after it was
created:

    def new_default_hello(self):
        print "hello, children"

    A.say_hello = new_default_hello


Notice that you need to use self when assigning it to the class
object, and not to use self when assigning it to an instance of the
class.


Carl Banks



More information about the Python-list mailing list