decorator needs access to variables where it is used.

Peter Otten __peter__ at web.de
Wed Oct 9 07:52:47 EDT 2019


Antoon Pardon wrote:

> I have some logging utilities so that when I write library code, I just
> use the following.
> 
> from logutil import Logger
> 
> log = Logger(__name__)

If logutil is under your control you can make log a callable object with a 
tracing method:

[logutil.py]

class Logger:
    def __call__(self, ...):
        # what log() currently does

    def traced(self, func):
        def trace(*args):
            self(DEBUG, "=> %s%s" % (func.__name__, args))
            result = func(*args)
            self(DEBUG, "%s => %s" (func.__name__, result))
            return result
        return trace

[useit.py]

from logutil import Logger
log = Logger(__name__)

@log.traced
def some_func(...): ...

But yes, Chris' suggestion is more straight-forward ;)

> And from then on I just use log, to do the logging of that module.
> 
> But now I would like to write a decorator trace, so that a decorated
> function would log, its arguments and result.
> 
> Something like:
> 
> def trace(func):
> 
>     def wrapper(*args):
>         log(DEBUG, "=> %s%s" % (func.__name__, args))
>         result = func(*args)
>         log(DEBUG, "%s => %s" (func.__name__, result))
> 
>     return wrapper
> 
> The problem is that with this decorater, the log function
> used, will be the log function defined where the decorator
> is written and I would prefer it to use the log function
> where it is used, so that it uses the same log function
> as the function it decorates.





More information about the Python-list mailing list