首页 > 解决方案 > 如何模拟遗留函数的文件名以提供已经在内存中的数据?

问题描述

我想使用一个接收文件名作为参数的遗留函数。该函数将在打开该文件后进行一些处理。

def legacy_f(filename):
    with open(filename, 'r') as fh:
        # some processing

但我希望处理发生在一些已经加载到某个变量中的数据中,而不是在文件中。由于性能原因,首先将数据保存到文件不是解决方案。有没有办法“愚弄”遗留功能使其认为它正在打开文件?

我的情况正是这个问题中的情况,但是那里接受的答案建议使用tempfile.NamedTemporaryFile,(我相信)确实会在磁盘中创建一个文件。我买不起。

标签: python

解决方案


嗯,这有点 hacky,可能不是一个好的做法,但你可以在上下文管理器中修改 open 函数。这不会取代 open,而只是用该上下文管理器中的其他内容对其进行修补。您可以查看我是否再次调用该函数,但在上下文管理器之外它会恢复为使用内置打开。

然而,这种类型的模拟通常用于测试。

from unittest import mock


def legacy_f(filename):
    with open(filename, 'r') as fh:
        for line in fh:
            print(line, end="")
        print()

data = "this\nis\nsome\ndata"
filename = "somefile"

#patch the open call
with mock.patch('builtins.open', mock.mock_open(read_data=data)):
    legacy_f(filename)

#the patch only works in the conext manager, outside its the normal open
try:
    legacy_f(filename)
except FileNotFoundError:
    print(f"file '{filename}' not found since we only patch in the context manager")

输出

this
is
some
data
file 'somefile' not found since we only patch in the context manager

推荐阅读