嵌套Python上下文管理器

问题描述 投票:8回答:2

this question中,我定义了一个包含上下文管理器的上下文管理器。完成此嵌套的最简单的正确方法是什么?我最终在self.temporary_file.__enter__()中呼叫了self.__enter__()。但是,在self.__exit__中,我很确定我必须在finally块中调用self.temporary_file.__exit__(type_, value, traceback),以防引发异常。如果self.__exit__中出现问题,是否应该设置type_,value和traceback参数?我检查了contextlib,但找不到任何实用程序来帮助解决此问题。

原始问题代码:

import itertools as it
import tempfile

class WriteOnChangeFile:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.temporary_file = tempfile.TemporaryFile('r+')
        self.f = self.temporary_file.__enter__()
        return self.f

    def __exit__(self, type_, value, traceback):
        try:
            try:
                with open(self.filename, 'r') as real_f:
                    self.f.seek(0)
                    overwrite = any(
                        l != real_l
                        for l, real_l in it.zip_longest(self.f, real_f))
            except IOError:
                overwrite = True
            if overwrite:
                with open(self.filename, 'w') as real_f:
                    self.f.seek(0)
                    for l in self.f:
                        real_f.write(l)
        finally:
            self.temporary_file.__exit__(type_, value, traceback)
python contextmanager
2个回答
10
投票

创建上下文管理器的简单方法是使用contextlib.contextmanager。像这样的东西:

contextlib.contextmanager

然后使用@contextlib.contextmanager def write_on_change_file(filename): with tempfile.TemporaryFile('r+') as temporary_file: yield temporary_file try: ... some saving logic that you had in __exit__ ... with write_on_change_file(...) as f:语句的主体将“代替” with执行。如果要捕获主体中发生的任何异常,请将yield本身包装在yield块中。

临时文件将始终正确关闭(当其try块结束时。)>


0
投票

with非常适合功能,但是当我需要一个类作为上下文管理器时,我正在使用以下实用程序:

© www.soinside.com 2019 - 2024. All rights reserved.