[Python-Dev] Re: Another approach to decorators.

Tim Hochberg tim.hochberg at ieee.org
Thu Aug 12 06:08:37 CEST 2004


Jp Calderone wrote:
> David Eppstein wrote:
> 
>> In article <un011l2qz.fsf at boost-consulting.com>,
>>  David Abrahams <dave at boost-consulting.com> wrote:
>>
>>
>>>> class Foo:
>>>>
>>>>  decorate static:
>>>>
>>>>    def static1(blah...):
>>>>        pass
>>>>
>>>>    decorate locksFile:
>>>>
>>>>      def static2andLocks(blah...):  # both decorators appy
>>>>          pass
>>>
>>>
>>> Wow, Martin Z's idea (using your keyword) really went "thunk" for me.
>>> What decorate does would be very much like what "class" does in some
>>> ways.
>>
>>
>>
>> class: (and other something: constructs) start a block that can 
>> contain any code.  Does this decorate keyword allow e.g. assignments 
>> as well as defs and other decorates?  Or loops?  If so what should it 
>> mean?  Is it like that locals() gets replaced by a special 
>> dictionary-like-object that calls the decorator whenever any of its 
>> contents gets set?
>>
> 
>   (I have no idea what the original poster intended, however....)
> 
>     'decorate' expression ':'
>         suite
> 
>   could create a nested scope, the locals of which could be passed to 
> whatever "expression" evaluates to (or if it is a tuple, do the looping 
> thing, since people seem to like that).
> 
>   The call can return a dict with which the class dict is updated.

FWIW, I proposed something very similar to this on python-list 
(http://mail.python.org/pipermail/python-list/2004-August/233262.html). 
It didn't get a very excited reception there. I think deafening silence 
is the phrase I'd use. But perhaps it'll inspire some new thoughts on 
your proposal.

The gist of my proposal was that:

     'def' name 'as' expression ':'
          suite

would bind name to the result of expression where expression was 
evaluated in the scope of suite, after suite was executed. So, to reuse 
the example below:

      class Foo(object):
          def bar as staticmethod(bar):
              def bar(x):
                  print 'spam', x

For several more examples, see the original post.

-tim

> 
>   For that matter, 'decorate' could even be dropped, to avoid 
> introducing a new keyword.  I don't think
> 
>     expression ':'
>         suite
> 
>   means anything in the current grammar.  This would mean staticmethod 
> and classmethod would no longer work (unless we really want them to - 
> they can do type checking on their argument and modify their behavior 
> accordingly).  Replacement implementations would be simple.  In fact, 
> making any current decorator work with this new mechanism is easy:
> 
>     def forall(decorator):
>         def new_decorator(namespace):
>             for k, v in namespace.items():
>                 namespace[k] = decorator(v)
>             return namespace
>         return new_decorator
> 
>     class Foo(object):
>         forall(staticmethod):
>             def bar(x):
>                 print 'spam', x
> 
>   Many decorators would probably be used with something like forall, or 
> simply support dicts directly.  Of course, many would want to work some 
> other way.
> 
>   For the PyObjC crowd, I think this would remove a major use of 
> metaclasses (as people have argued that metaclasses are hard to 
> understand and best avoided for simple decoration, this seems to be a 
> good thing).  I can also think of some terrible, terrible metaclass 
> hackery in my own code that this would obviate the need for.
> 
>   This covers a use case James Knight mentioned as well.  As he pointed 
> out, '@' and other proposals only decorate functions (and maybe classes, 
> soon).  The example he gave, I believe, was:
> 
>     @public
>     x = 1
> 
>   This doesn't work, but:
> 
>     public:
>         x = 1
> 
>   would.  Now, swallow that scream of horror (I did, barely ;). "public" 
> here is intended to be defined as something like:
> 
>     def public(namespace):
>         __all__.extend(namespace.keys())
>         return namespace
> 
>   I can see the potential for confusion to new Python programmers here, 
> though, if they come from certain other languages.  Perhaps leaving the 
> keyword prefix would be best after all.
> 
>   Another possibility would be to pass a code object for the suite, 
> instead of a namespace.  I am inclined to prefer this, since it more 
> closely resembles the other construct which can create a nested scope. 
> It adds the burden of exec'ing the code to the decorator, though.  This 
> isn't a problem if something like "forall" above is included in the 
> stdlib, since the common case is dealt with already (thus people 
> desiring class or static methods need not know or care about it), and 
> more advanced users will value the power it affords over the minor 
> additional effort required to use it.
> 
>   Jp
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: 
> http://mail.python.org/mailman/options/python-dev/python-python-dev%40m.gmane.org 
> 
> 



More information about the Python-Dev mailing list