在 init 中使用 contextmanager

在下面的代码中,我不明白为什么with super().__init__(*args, **kwargs):MyFileIO2 中的行会抛出一个关于丢失的错误,__exit__而 MyFileIO 类一切正常。我真的不明白在 init 内部或外部执行 with 之间究竟有什么区别。有人可以启发我这里发生了什么吗?


import io


class MyFileIO(io.FileIO):

    def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)


    def __enter__(self, *args, **kwargs):

        f = super().__enter__(*args, **kwargs)

        print('first byte of file: ', f.read(1))

        return f


class MyFileIO2(io.FileIO):

    def __enter__(self, *args, **kwargs):

        f = super().__enter__(*args, **kwargs)

        print('first byte of file: ', f.read(1))

        return f


    def __init__(self, *args, **kwargs):

        with super().__init__(*args, **kwargs): # AttributeError: __exit__

            pass


path = 'some_file.bin'


with MyFileIO(path, 'rb'):

    pass


MyFileIO2(path, 'rb')


拉风的咖菲猫
浏览 170回答 1
1回答

MMTTMM

您将需要在 上调用上下文管理器self,因为__init__实际上不会返回任何内容。class MyFileIO2(io.FileIO):    def __init__(self, *args, **kwargs):        super().__init__(*args, **kwargs)        with self:             pass    def __enter__(self, *args, **kwargs):        f = super().__enter__(*args, **kwargs)        print('First byte of file: ', f.read(1))        return f为了测试,我创建了一个内容为“hello world”的二进制文件。_ = MyFileIO2(path, 'rb')    # First byte of file:  b'h'发生的事情是super().__init__通过上下文管理器传递的返回值,因此您有效地拥有:with None:     passAttributeError: __enter__上下文管理器尝试调用对象__enter__上的方法NoneType,但这是一个无效的操作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python