Ron_Adam wrote: > > # (0) Read defined functions into memory > > def decorator(d_arg): # (7) Get 'Goodbye' off stack > > def get_function(function): # (8) Get func object off stack > > def wrapper(f_arg): # (9) Get 'Hello' off stack > > new_arg = f_arg+'-'+d_arg > result = function(new_arg) # (10) Put new_arg on stack > # (11) Call func object > > return result # (14) Return result to wrapper > > return wrapper # (15) Return result to get_function > > return get_function # (16) Return result to caller of func > > > > @decorator('Goodbye') # (5) Put 'Goodbye' on stack > # (6) Do decorator > > def func(s): # (12) Get new_arg off stack > > return s # (13) Return s to result > > # (1) Done Reading definitions > > > print func('Hello') # (2) Put 'Hello' on stack > # (3) Put func object on stack > # (4) Do @decorator > # (17) print 'Hello-Goodbye' > > # Hello-Goodbye
Is it possible that you mistakenly believe your @decorator() is being executed at the line "func('Hello')"? Please add a print statement to your code: def decorator(d_arg): def get_function(function): print 'decorator invoked' def wrapper(f_arg): new_arg = f_arg+'-'+d_arg result = function(new_arg) return result return wrapper return get_function When you run the program, you will see that the comment "decorator invoked" is printed out at the moment when you finish defining: @decorator('Goodbye') def func(s): return s That is, decorator is invoked before you run the line "func('Hello')". Decorator feature is a metaprogramming feature. Not a programming feature. By metaprogramming I mean you are taking a function/code object, and try to do something with it (e.g., wrap it around.) By the time you finish defining the function "func(s)", the decorator "get_function()" was already invoked and will never be invoked again. It's better to view functions as individual objects. And try to think who holds reference to these objects. If no one holds reference to an object, it will be garbage collected and will be gone. After you define the function "func()" and before you execute "func('Hello')", this is the situation: decorator() <--- held by the module get_function() <--- temporary object, garbage collected wrapper() <--- held by the module, under the name "func" func() <--- held by wrapper(), under the name "function" 'Goodbye' <--- string object, held by the wrapper function object, under the name d_arg Objects can be rebound to different names. In your code you have rebound the original wrapper() and func() function objects to different names. I think the confusing part is that, for function name binding, Python does not use the = operator, but instead relies on the "def" keyword. Maybe this is something to be considered for Python 3K. Anonymous function or codeblock objects are good to have, when you are doing metaprogramming. -- http://mail.python.org/mailman/listinfo/python-list