Reputation: 943
As you may now, the common usage of decorator is for example:
@log
def func(...)
What actualy takes func as parameter returns a function what takes func as an argument, like :
def log(func):
def function_wrapper(*args , **kwargs):
log_enter_func(func, args, kwargs)
result = func(*args, **kwargs)
log_exit_func(func, result )
return result
In code above, logging of function calls and returns are fine, without hand- made log (...) entries with just @log decorator over a function. So its easy to remove after testing, so logging does not consume time.
But is it possible to hang it just to lines of code? Like for loops, etc, so something like :
def func(...):
...
@log
for x in range(whatever)
Taking the line as soft of a function, accessing in some kinf of args to x, whatever ( variables and code in the line) cause actualy everything is a function in python?
Or maybe there is some kind of method to apply decorator to a method and propagate it to source lines in a function ?
The idea is to make a brief logging of whats happens in every line without lots of hand- written log entries like log.info(msg) in many lines of code
Any ideas about that? I v tryed to inspect the func. __ code __ built- in, but its python byte- code there , not source code...
Upvotes: 2
Views: 5138
Reputation: 123
While it may not be possible to address each line of a function with a decorator, I think you may be able to log each line using the following method:
Python Decorator for printing every line executed by a function
The idea is to create a debug context, then the debug decorator wrapper around the debug_context function. This creates a log of local variables to std.out
Upvotes: 1
Reputation: 10819
No, decorators are meant to wrap functions only.
That said, you can run your line inside a function and then use the decorator.
def func(...):
...
@log
def _f(): #you can define this inside func() if you want
for x in range(whatever):
...
#call decorated function
_f()
Upvotes: 1
Reputation: 599866
This is exactly what context managers are for. These are triggered with a with
block, and define code that runs on entering and exiting the block.
See the documentation.
Upvotes: 3