[Python-Dev] Re: decorators and 2.4

David Abrahams dave at boost-consulting.com
Fri Jun 25 18:21:43 EDT 2004


"Phillip J. Eby" <pje at telecommunity.com> writes:

> At 08:26 AM 6/25/04 -0400, David Abrahams wrote:
>>"Phillip J. Eby" <pje at telecommunity.com> writes:
>> > You'd need to do something like keep a copy of the locals and on
>> > each "new line" event from the trace hook, you'd need to both call
>> > the old trace hook (so that debugging could still take place) and
>> > check to see if the locals had a new function object.  As soon as
>> > the function object appeared, you could do your dirty work (after
>> > first restoring the *old* value bound to that name, so the
>> > decorators would have access to the previous binding of the name).
>>
>>I'm perfectly happy for this decorate function to work on the very
>>next name binding; I don't think it's reasonable to expect to be able
>>to do anything else between it and the function definition.
>
> Keep in mind that this means code like this:
>
> decorate(foo)
> decorate(bar(baz=[x*2 for x in y]))
> def spam():
>      pass
>
> Will likely fail horribly, applying the 'foo' decorator to the first
> element of 'y' before trying to multiply by 2, or worse, possibly

"doctor, it hurts when I do this..."

> applying them to the "anonymous" list object that's created to hold
> the results of the list comprehension.  Or, it might sometimes *seem*
> to work due to hashing order and the vagaries of when 'line' events
> fire, and then fail in a new release of Python.  This is why I
> consider it somewhat of a wart in the current implementation, as I
> note below...

That's why decorate should take a variable number of arguments:

decorate(foo, bar(baz=[x*2 for x in y]))
def spam():
     pass

>> > Anyway, it works with CPython 2.2.  Caveat: do *not* use listcomps or
>> > any other assignment statements between your 'decorate()' invocation
>> > and the function definition, or the decorators will be applied to the
>> > bound-to variable!
>> >
>> > Personally, I think the 'decorate()' function is probably actually not
>> > that useful, compared to making specialized decoration functions like,
>> > say:
>> >
>> >     classmethod_follows()
>> >     def foo(klass, x, y, z):
>> >         # ...
>>
>>Ick!
>
> Is it the name you dislike?  Or the idea of simply invoking decorating
> functions directly?

What I want is a recognizable syntax that indicates decoration.  If
it's likely to be any old function name, decorators are much less
likely to jump out at you.  In fact, that's why I really like
operator syntaxes like:

  with[foo, bar(baz=[x*2 for x in y])]
  def spam():
       pass

or something.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com




More information about the Python-Dev mailing list