Poll - Vote here for "list-after-def" (was Decorator syntax)

Bengt Richter bokr at oz.net
Fri Aug 6 16:19:56 EDT 2004


On Fri, 06 Aug 2004 08:24:47 -0400, Peter Hansen <peter at engcorp.com> wrote:

>Istvan Albert wrote:
>
>> Paul McGuire wrote:
>> 
>>  > Please reconsider the "def f() [classmethod]:" construct.  
>>  >
>>  > def f() [ staticmethod,
>>  >     synchronized,
>>  >     alphabetized,
>>  >     supersized,
>>  >     returns('d') ]:
>
>Nobody has bothered to post an example with a long argument list,
>thus ignoring the possibly valid claim in the PEP that this would
>make the decorator list hard to see.  Here goes:
>
>     def someMethod(self, posArgOne, anotherArg,
>         fieldX=56,
>         x=5, y=7, z=9,
>         **kwargs)
>         [
>         staticmethod,
>         synchronized,
>         alphabetized,
>         supersized,
>         returns('d')
>         ]:
>
>Okay, pretty much an abomination, but I'm not sure it's any worse than
>the alternative with @:
>
>     @staticmethod
>     @synchronized
>     @alphabetized
>     @supersized
>     @returns('d')
>     def someMethod(self, posArgOne, anotherArg,
>         fieldX=56,
>         x=5, y=7, z=9,
>         **kwargs):
>
>It *is*, however, fairly clear that the list of decorators becomes
>harder to see.  Without checking, it's definitely possible that the
>decorator list in the first case is actually part of the argument list.
>
It seems to me that all the proposed syntaxes have in common the purpose
of creating an ordered set of functions to be applied in order to the
result of a def. Why not accept this and use a builtin object to hold
the temporary function sequence? Thus you could have a method (or __call__)
add one or more functions to the temporary set contained in the builtin object.

Then the list of functions can be the argument list to a method of the builtin
object instead of list syntax magically interpreted in list-after-def context,
magically saving the sequence in a magic internal place (as opposed to programmer-known
and overrideable). If you had a builtin object and a builtin userfriendly
alias for a method that adds one or more decorators to its list (that gets used
up at the end of the next def), then you could write (picking decorate as user-friendly ;-)

      decorate(staticmethod, synchronized, alphabetized, supersized)
      decorate(returns('d'))
      def someMethod(self, posArgOne, anotherArg,
          fieldX=56,
          x=5, y=7, z=9,
          **kwargs
      ):                   #I like it better here for multiline arg lists ;-)
          # ...

def implementation would have to be modified to look for the builtin object
and get the decorator functions from there. You could choose to look for
a shadowing name binding starting with locals(), or you could only allow
a shadowing starting at globals() I suppose, for speed.

BTW, is @decorator thread-safe? I guess it would be something to be careful
about in a really dynamic object-oriented implementation.

>I don't care.  I still prefer it to @, if nothing else because
>it's much more intuitive to a Python programmer what order they
>will be applied in.
>
'@x' as a spelling of
__programmer_inaccessible_hidden_system_temp_list.append(x) # or is it 'x' ?
seems not the best use of '@' to me.

Regards,
Bengt Richter



More information about the Python-list mailing list