Logging function calls without changing code

Matt Wheeler m at funkyhat.org
Wed May 24 19:46:52 EDT 2017


Hi Rajat,

On Wed, 24 May 2017 at 20:05 Rajat Sharma <rajat.sharma.2 at asu.edu> wrote:

> Is there a way to log all function calls of a class without changing
> anything in that class.
>

Several... depending on what you want to achieve some may be more suited
than others


> What I mean to say is if I have written a class previously and I want to
> enable logging in that then I would probably need to write the following
> before my function calls-
>
> logger.debug('<function name> called...')
>
> But, is there a way that I do not need to change my existing code and can
> create a wrapper around that existing class or something else which can
> help me do the same?
>

My first thought is why not write a simple wrapper class like so:

```
class Wrapper(Original):
    def __init__(self, *args, **kwargs):
        _wrapped = Original(*args, **kwargs)

    def __getattr__(self, attr):
        print('accessed {}'.format(attr))
        return getattr(self._wrapped(attr))
```

This could easily be translated into a decorator so that you can apply it
directly to the original class, something like:
```
def log_accesses(cls):
    class Wrapper(object):
        def __init__(self, *args, **kwargs):
            self._wrapped = cls(*args, **kwargs)

        def __getattr__(self, attr):
            print('accessed {}'.format(attr))
            return getattr(self._wrapped(attr)

    return Wrapper

@log_accesses
class Original(......
```

If you want to also log the arguments passed to the functions (you didn't
say that) things get a bit more complex, but it's still certainly
achievable.

If you actually need to wrap the class in place for testing you might look
into combining something like the above with the mock library.
-- 

--
Matt Wheeler
http://funkyh.at



More information about the Python-list mailing list