当与' as'一起使用时覆盖python open函数。打印任何关键字

时间:2017-08-30 00:39:33

标签: python

如何覆盖内置的open函数,以便在我调用它时...

with open(file_path, "r") as f:
    contents = f.read()

contents变量是我想要的任何字符串吗?

编辑:为了澄清,我希望能够只为开放函数提供一个字符串,而不是一个将被读取的文件路径。

with open("foobar") as f:
    contents = f.read()
    print(contents)

上面应该打印foobar。

我知道这会破坏open等的目的,但它是出于测试目的。

3 个答案:

答案 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)

然后,您可以编写所需的逻辑来确定readFile.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!

更多阅读:http://effbot.org/zone/python-with-statement.htm