有没有办法检查我的代码的哪一部分让文件句柄打开

Ana*_*C U 4 python file-handling python-3.x

有没有办法跟踪python进程来检查文件被打开的位置。我lsof在运行过程中使用时打开了太多文件,但我不确定它们是在哪里打开的。

ls /proc/$pid/fd/ | wc -l
Run Code Online (Sandbox Code Playgroud)

我怀疑我使用的库之一可能没有正确处理文件。有没有办法准确地隔离正在打开文件的python代码中的哪一行?

在我的代码中,我使用 3rd 方库来处理数千个媒体文件,由于它们处于打开状态,我收到了错误

OSError: [Errno 24] Too many open files
Run Code Online (Sandbox Code Playgroud)

运行几分钟后。现在我知道提高打开文件的限制是一个选项,但这只会将错误推到以后的时间点。

小智 8

跟踪open调用的最简单方法是在 Python 中使用审计挂钩。请注意,此方法只会跟踪 Pythonopen调用而不是系统调用。

让我们fdmod.py成为一个具有单个功能的模块文件foo

def foo():
    return open("/dev/zero", mode="r")
Run Code Online (Sandbox Code Playgroud)

现在文件fd_trace.py中跟踪所有open调用和导入的主要代码fdmod定义如下:

import sys
import inspect
import fdmod

def open_audit_hook(name, *args):
    if name == "open":
        print(name, *args, "was called:")
        caller = inspect.currentframe()
        while caller := caller.f_back:
            print(f"\tFunction {caller.f_code.co_name} "
                  f"in {caller.f_code.co_filename}:"
                  f"{caller.f_lineno}"
            )
sys.addaudithook(open_audit_hook)

# main code
fdmod.foo()
with open("/dev/null", "w") as dev_null:
    dev_null.write("hi")
fdmod.foo()
Run Code Online (Sandbox Code Playgroud)

当我们运行时fd_trace.py,只要某个组件正在调用,我们就会打印调用堆栈open

% python3 fd_trace.py
open ('/dev/zero', 'r', 524288) was called:
        Function foo in /home/tkrennwa/fdmod.py:2
        Function <module> in fd_trace.py:17
open ('/dev/null', 'w', 524865) was called:
        Function <module> in fd_trace.py:18
open ('/dev/zero', 'r', 524288) was called:
        Function foo in /home/tkrennwa/fdmod.py:2
        Function <module> in fd_trace.py:20
Run Code Online (Sandbox Code Playgroud)

查看sys.audithookinspect.currentframe了解详情。