Decorater inside a function? Is there a way?

Ron_Adam radam2 at tampabay.rr.com
Fri Apr 1 20:40:56 EST 2005


On Fri, 01 Apr 2005 16:46:14 -0500, Jeremy Bowers <jerf at jerf.org>
wrote:

>On Fri, 01 Apr 2005 19:56:55 +0000, Ron_Adam wrote:
>
>> On Fri, 01 Apr 2005 13:47:06 -0500, Jeremy Bowers <jerf at jerf.org>
>> wrote:
>>>Is this an April Fools gag? If so, it's not a very good one as it's quite
>>>in line with the sort of question I've seen many times before. "I have
>>>a hammer, how do I use it to inflate my tire?"
>> 
>> Not an April fools gag, I'm just new to decorators and google brings
>> up lots of discussions from the past on how they may be implemented in
>> the future, but not much in actually how they work or how to use them.
>
>OK, just checking :-)
>
>A decorator is completely equivalent in principle to
>
>def function():
>	pass
>function = decorator(function)

This helped some.  Thanks.

>That's a simplified form; decorators can themselves be an expression which
>returns a callable that can be applied to a function and the rule for
>applying several in sequence work as you'd expect (pipelining earlier
>results into later ones, making for a great Obfuscated Python entry or
>two based on the "function name misdirection" trick), but this simplified
>form captures the essense, which is what I think you're looking for. In
>particular, it's just "syntax sugar", not a "special feature".

Are you sure?  There appears to be some magic involved with these,
things happening under the hood with argument passing.  

def decorate(function):
    def wrapper(args):
        print 'args' = args
        return function(args)
    return wrapper

@decorate
def func(s):
    print s

func('hello')

In this example, how does wrapper get the correct arguments? This
leads me to believe what I'm looking for is possible, yet in this case
there isn't any way to pass, new arguments to the wrapper without
loosing the original ones.

Wait a min, hold the phone.. Eureka!  :)  I just figured how to do it.

(after trying it in idle)

def append_arg(n_args):
    def get_function(function):
        def wrapper(args):
            return function(args+'-'+n_args)
        return wrapper
    return get_function

@append_arg('goodbye')
def func(s):
    print s

func('hello')

prints:

hello-goodbye

Ok, this isn't a very useful example, but it demonstrates something
important. That, there seems to be a stack involved in the argument
passing of nested defined functions.  Any arguments passed in the
decorators get puts on top of the stack. And nested functions pull
them back off.  Does this sound right?

I still feel it can be simplified a bit. These aren't easy to
understand, and having to nest functions like this adds to the
confusion. possibly being able to get the argument "stack", as it
appears to be, directly in the first level could make things a lot
easier.


>
>Feeling-like-I-owed-you-an-answer-after-the-april-fool-accusation-ly yrs,
>Jeremy Bowers
>:-)

Thanks, it helped. :)



More information about the Python-list mailing list