如果上下文对象在没有使用'的情况下使用

时间:2016-05-22 19:51:16

标签: python-3.x contextmanager

我不太确定如何为自定义类实现上下文管理器。基本上它只是接受__init__中的文件名,在__enter__中打开文件并在__exit__中关闭它。

,例如:

class BlaFile:
    def __init__(self, file_name):
        self.file_name = file_name

    def __enter__(self):
        self.file = open(self.file_name, "rb")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

    def do_stuff_with_file():
        # This will fail when I'm using this class without 'with'.
        return self.file.read(1)

但是,当我不打算使用''来实例化/使用该课程时。声明,我将无法使用访问该文件的任何函数,因为__enter__从未被调用过;因此文件没有打开。

也许我在这里过于倾向于使用C#' using关键字;但即使我没有使用with关键字,我也不能正确使用该课程的实例吗?现在我被迫用它 - 这是Python中的典型用法吗?

2 个答案:

答案 0 :(得分:0)

你需要使用open() 要通过阅读打开,您需要更改为:

class BlaFile:
    def __init__(self, file_name):
        self.file_name = file_name
        self.file = open(self.file_name, "r+b")
    def close(self):
        self.file.close()

    def do_stuff_with_file(self):
        return self.file.read(1)

这应该可以解决问题。

答案 1 :(得分:0)

如果您希望打开文件而不管是否在with中使用该文件,则需要使用__init__方法打开该文件。由于用户可能忘记关闭文件,我建议您在退出时注册结束:

from atexit import register

class BlaFile:
    def __init__(self, file_name):
        self.file_name = file_name
        self.file = open(file_name, 'rb')
        register(self.file.close)

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

    def do_stuff_with_file(self):
        return self.file.read(1)