Docorator Disected
Ron_Adam
radam2 at tampabay.rr.com
Sun Apr 3 22:13:29 EDT 2005
On Sun, 03 Apr 2005 23:59:51 +0200, "Martin v. Löwis"
<martin at v.loewis.de> wrote:
>Ron_Adam wrote:
>> This would be the same without the nesting:
>>
>> def foo(xx):
>> global x
>> x = xx
>> return fee
>>
>> def fee(y):
>> global x
>> return y*x
>>
>> z = foo(2)(6)
>
>Actually, it wouldn't.
Ok, yes, besides the globals, but I figured that part is obvious so I
didn't feel I needed to mention it. The function call works the same
even though they are not nested functions.
>>
>> It's not entirely a misconception. Lets see where this goes...
>>
>>
>>>>>>dis.dis(compiler.compile('foo(2)(6)','','eval'))
>>>
>>> 1 0 LOAD_NAME 0 (foo)
>>> 3 LOAD_CONST 1 (2)
>>> 6 CALL_FUNCTION 1
>>> 9 LOAD_CONST 2 (6)
>>> 12 CALL_FUNCTION 1
>>> 15 RETURN_VALUE
>
>Hmm. If you think that this proves that (2)(6) is being *passed*, you
>still might have a misconception. What this really does is:
I didn't say they were passed at the same time by the stack. It just
shows my reference to *stacks* was correct, and that there's is an
underlying mechanism for calling functions and passing arguments and
functions that use the stack. I however was not yet aware (yesterday
afternoon) of just how the stack worked in this case. This was very
much a figure it out as you go exercise.
Yesterday, I had made the incorrect judgement that since the functions
are all nested inside a defined function, that I should treat them as
a group instead of individual functions. But that wasn't the correct
way of viewing it. They are in a group in that they share name space,
so I figured, (incorectly), that they shared an argument list somehow,
and those where passed to the group. The passing of the function, and
it's arguments silently was a big reason for me jumping to this
conclusion.
So my reference to:
>>The interesting thing about this is the 'return fee' statement gets
>>the (6) apparently appended to it. So it becomes 'return fee(6).
Which is not correct, as the order of events is wrong and they do not
share a common argument list.
The correct order is:
return fee
fee(6)
with the fee(6) being evaluated after the return statement is
executed.
Another contributing factor is two days of really poor sleep. Which
probably is a bigger factor than I would like to admit. I really feel
I should have gotten it much sooner. But I did get-it, a little bit
at a time, and had a lot of terrific help along the way. :-)
<clip>
>> Or it could be said equally the functions (objects) are passed with
>> the stack. So both view are correct depending on the view point that
>> is chosen.
>
>Maybe I don't understand your view, when you said
>
># No, I did not know that you could pass multiple sets of arguments to
># nested defined functions in that manner.
My views have changed as I added the missing peices to the puzzle
yesterday.
At first I didn't see how they were passed at all, in a group or
otherwise. There wasn't any one-to-one way to match the arguments up
visually like there are in a normal function call.
My next thought was they are passed as a group, to the group of
defined functions that shared the same name space. (Everyone seems to
think I'm stuck on this one.)
My Next view, yesterday afternoon, was they were passed on a stack
somehow one at a time. This last one is not necessarily incorrect from
a byte code viewpoint, but it's not the best way to view the problem.
Today I believe I have the correct view as I've said this morning. I
could be wrong yet again. I hope not though I might have to give up
programming. :/
It's interesting that I have had several others tell me they had
trouble with this too.
So it is my opinion that decorators are a little too implicit. I
think there should be a way to make them easier to use while achieving
the same objective and use.
Thanks again for the reply, :)
Cheers,
Ron
More information about the Python-list
mailing list