如何覆盖内置的open
函数,以便在我调用它时...
with open(file_path, "r") as f:
contents = f.read()
contents
变量是我想要的任何字符串吗?
编辑:为了澄清,我希望能够只为开放函数提供一个字符串,而不是一个将被读取的文件路径。
with open("foobar") as f:
contents = f.read()
print(contents)
上面应该打印foobar。
我知道这会破坏open等的目的,但它是出于测试目的。
答案 0 :(得分:2)
考虑到它是出于测试目的而你想强制开放调用返回一个特定字符串,那么你可以在这里使用mock_open
。
假设我有一个模块foo
,它有一个从文件中读取内容并计算行数的函数:
# foo.py
def read_and_process_file():
with open('Pickle Rick') as f:
contents = f.read()
print('File has {n} lines'.format(n=len(contents.splitlines())))
现在,在您的测试中,您可以模拟此模块的open
并使其返回您想要的任何字符串:
from unittest.mock import mock_open, patch
import foo
m = mock_open(read_data='I am some random data\nthat spans over 2 lines')
with patch('foo.open', m):
foo.read_and_process_file() # prints 2
答案 1 :(得分:1)
您可以创建自己的类文件类型,并使用自己的open
函数覆盖内置open
。
import builtins
class File(object):
"""A basic file-like object."""
def __init__(self, path, *args, **kwargs):
self._file = builtins.open(path, *args, **kwargs)
def read(self, n_bytes = -1):
data = self._file.read(n_bytes)
...
return data
def __enter__(self):
return self
def __exit__(self, e_type, e_val, e_tb):
self._file.close()
self._file = None
def open(path, *args, **kwargs):
return File(path, *args, **kwargs)
然后,您可以编写所需的逻辑来确定read
内File.read
的返回值。
答案 2 :(得分:0)
您可以设计自己的类,因为需要具有已定义的__enter__
和__exit__
方法的对象。正如那样。
class my_class:
def __init__(self, *args):
print("initializing variable, got args: {}".format(args))
def __enter__(self):
print("Inside enter statement!")
return "arbitrary text"
def __exit__(self, type, value, traceback):
print("closing time, you don't have to go home")
return
with my_class(1,2,3) as my_thing:
print("inside the with block!")
print("The return from my_class __enter__ is: ", my_thing)
print("Outside with block!")
运行时输出:
initializing variable, got args: (1, 2, 3)
Inside enter statement!
inside the with block!
The return from my_class __enter__ is: arbitrary text
closing time, you don't have to go home
Outside with block!