manipulating class attributes from a decorator while the class is being defined

Arnaud Delobelle arnodel at googlemail.com
Sun Apr 20 02:17:58 EDT 2008


On Apr 19, 10:19 pm, Wilbert Berendsen <wbs... at xs4all.nl> wrote:
> Hi, is it possible to manipulate class attributes from within a decorator
> while the class is being defined?
>
> I want to register methods with some additional values in a class attribute.
> But I can't get a decorator to change a class attribute while the class is
> still being defined. Something like:
>
> class Parser(object):
>
>   regexps = []
>   def reg(regexp):
>     def deco(func):
>       regexps.append((regexp, func))
>       return func
>     return deco
>
>   @reg(r'".*"')
>   def quoted_string(self):
>     pass
>
> How can I reach the class attribute `regexps' from within a decorator?

In this particular example, it is enought to change the line

   def reg(regexp):

to:

   def reg(regexp, regexps=regexps):

So that 'regexps' inside reg() will point to the same object as
'regexps' outside reg().

Of course it wouldn't work well with inheritance, but it seems to me
that you don't want to subclass 'Parser' anyway.  If you did, you
could instead have something like this:

class Ruleset(list):

    def add(self, regexp):
        def decorator(func):
            self.append((regexp, func))
            return func
        return decorator


class Parser(object):

    rules = Ruleset()

    @rules.add(r'".*"')
    def quoted_string(self):
       pass


Or, yet another solution is to change the metaclass of 'Parser' so
that it populates the class's rules by scanning its attributes.

HTH

--
Arnaud




More information about the Python-list mailing list