How can I override the built in open
function such that when I call it like so…
with open(file_path, "r") as f: contents = f.read()
The contents
variable is any string I want?
EDIT: To clarify, I want to be able to just provide a string to the open function rather than a file path that will be read.
with open("foobar") as f: contents = f.read() print(contents)
The above should print foobar.
I am aware this is defeating the purpose of open etc but it is for testing purposes.
Advertisement
Answer
You can create your own file-like type and override the builtin open
with your own open
function.
import builtins import contextlib class File(object): """ A basic file-like object. """ def __init__(self, path, *args, **kwargs): self._fobj = builtins.open(path, *args, **kwargs) def read(self, n_bytes = -1): data = self._fobj.read(n_bytes) ... return data def close(self): self._fobj.close() @contextlib.contextmanager def open(path, *args, **kwargs): fobj = File(path, *args, **kwargs) try: with contextlib.closing(fobj): yield fobj finally: pass
You can add whatever behavior or additional logic needed to adjust the return value of read()
inside File.read
itself, or override the behavior entirely from a subclass of File
.
Simplified for the particular case in question:
class File(str): def read(self): return str(self) @contextlib.contextmanager def open(string): try: yield File(string) finally: pass with open('foobar') as f: print(f.read())