Skip to content
Advertisement

Override python open function when used with the ‘as’ keyword to print anything

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())
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement