0

I am writing a function decorator to perform profiling of a function, it stores information about the function during execution and outputs the information into a log file. The implementation causing issues can be seen below.

import time
import sys

class _profile:
    def __init__(self, func, filepath):
        self.func = func
        self.filepath = filepath
        self.calls = []
    def __call__(self, *args, **kwargs):
        start = time.time()
        result = self.func(*args, **kwargs)
        self.calls.append(time.time() - start)
        return result
    def __del__(self):
        mean = sum(self.calls)/len(self.calls)
        with open(self.filepath, "a+") as out_file:
            output = f"'{self.func.__name__}' called {len(self.calls)} times, mean execution time of {mean}"
            out_file.write(output)

def profile(filepath=sys.stdout):
    def _profile_impl(func):
        return _profile(func, filepath)
    return _profile_impl

@profile("function.log")
def add(a, b):
    return a + b

def main():
    for i in range(100):
        add(i, i)

if __name__ == "__main__":
    main()

This is the same issue which was found in this question; summarised, the open() function is removed from __builtins__ before __del__ is called for objects in the global scope. However, the solution is not as simple as putting the offending object in a function scope as this is a function decorator which will need to work in the global scope. Are there any workarounds to this issue?

4
  • You shouldn't use __del__ for this, for objects alive at the time of interpreter shutdown, it isn't guaranteed to be called. Commented Aug 30, 2023 at 22:42
  • Can you suggest any alternatives to get this to work without increasing the amount of boilerplate code required to make use of the profile decorator? Commented Aug 30, 2023 at 22:43
  • 1
    Take a look at: docs.python.org/3/library/atexit.html Commented Aug 30, 2023 at 22:46
  • 1
    That's brilliant, I wish I found about that sooner. Thanks for the help! Commented Aug 30, 2023 at 22:49

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.