在函数装饰器的“__del__()”中调用“open()”的解决方法

Workaround for calling `open()` in `__del__()` for a function decorator

提问人:finlay morrison 提问时间:8/31/2023 更新时间:8/31/2023 访问量:26

问:

我正在编写一个函数装饰器来执行函数分析,它在执行过程中存储有关函数的信息并将信息输出到日志文件中。导致问题的实现如下所示。

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()

这与这个问题中发现的问题相同;总而言之,在为全局范围内的对象调用之前删除了该函数。但是,解决方案并不像将有问题的对象放在函数作用域中那么简单,因为这是一个函数装饰器,需要在全局作用域中工作。此问题是否有任何解决方法?open()__builtins____del__

Python 作用域 装饰器 内置 del

评论

0赞 juanpa.arrivillaga 8/31/2023
您不应该为此使用,对于在解释器关闭时处于活动状态的对象,不能保证它被调用。__del__
0赞 finlay morrison 8/31/2023
您能否建议任何替代方案来使其工作,而不会增加使用配置文件装饰器所需的样板代码量?
1赞 juanpa.arrivillaga 8/31/2023
看一看: docs.python.org/3/library/atexit.html
1赞 finlay morrison 8/31/2023
这太棒了,我希望我能早点发现。感谢您的帮助!

答: 暂无答案