是否有某种方法可以“捕获”对特定文件 /my/special/file
的所有尝试写入,并将其写入 BytesIO
或 StringIO
对象,或者其他一些无需实际写入磁盘即可获得该输出的方法?
用例是:有一个“处理程序”函数,其约定是将其输出写入/my/special/file
。我对这个 handler
函数没有任何控制——我不写它,我不知道它的内容,我不能改变它的内容,契约(Contract)也不能改变。我希望能够做这样的事情:
# 'output' has whatever 'handler' has written to `/my/special/file`
output = handler.run(data)
即使这是一个奇怪的请求,我也希望即使有一个“hackier”答案也能做到这一点。
编辑:我的代码(和处理程序
)将在大量数据 block 上被多次调用,因此性能(延迟和吞吐量)很重要。
谢谢。
最佳答案
如果您正在谈论您自己的 Python 程序中的代码,您可以在调用该代码之前对内置的 open
函数进行猴子修补。这是一个非常愚蠢的例子,但它表明你可以做到这一点。这会导致认为它正在写入文件的代码改为写入内存缓冲区。然后调用代码打印外部代码写入文件的内容:
import io
# The function you don't have access to that writes to a file
def foo():
f = open("/tmp/foo", "w")
f.write("blahblahblah\n")
f.close()
# The buffer to contain the captured text
capture_buffer = ""
# My silly file-like object that only handles write(str) and close()
class MyFileClass:
def write(self, str):
global capture_buffer
capture_buffer += str
def close(self):
pass
# patch open to return a MyFileClass instance
def my_open2(*args, **kwargs):
return MyFileClass()
open = my_open2
# Call the target function
foo()
# Print what the function wrote to "the file"
print(capture_buffer)
结果:
blahblahblah
很抱歉没有花更多时间在这上面。只是告诉你这是可能的。正如其他人所说,模拟模块可能是不必在这里发展自己的东西的方式。我不知道他们是否允许访问所写内容。我想他们必须。这样的模块只会更好地完成我在此处展示的内容。
如果您的程序使用open
执行其他文件 IO,或者神秘代码使用任何方法打开文件,您将检查传入路径并且只返回您的特殊对象(如果它是那个)您感兴趣的路径。否则,您可以只调用原始的 open
,您可以将其隐藏在另一个名称下。
关于Python:捕获对内存中文件的所有写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55912576/