如何在不关闭资源的情况下留下`with`块?

Vog*_*ang 2 python with-statement

我正在努力实现类似于

from tempfile import TemporaryFile

def open_head(file_path):
   with open(file_path, 'r') as f,
        TemporaryFile() as tf:
       for i in range(0,10):
           tf.write(f.read_line())
       return tf
Run Code Online (Sandbox Code Playgroud)

以便调用者获得临时文件的所有权。

特别是,我不希望该with语句关闭TemporaryFile. 但是如果在 之前出现任何问题return,我仍然希望TemporaryFilewith语句关闭。

理想情况下,我想将调用者写为

with open_head(file_path):
    # more code here
Run Code Online (Sandbox Code Playgroud)

这有可能吗?例如,通过编写return do_not_close(tf)或其他一些实用功能?

或者我是否完全错误地处理了这个问题,并且TemporaryFiles在保证异常安全的同时,还有一种更 Pythonic 的方式来返回 a或其他资源,在函数之间?

che*_*ner 6

你没有。open_head应该采用一个已经打开的句柄,调用者负责关闭它。

from tempfile import TemporaryFile
from itertools import islice


def head(file_path, fh):
    with open(file_path) as f:
        for line in islice(f, 10):
            fh.write(line)


with TemporaryFile() as tf:
    head(file_path, tf)
    # Do other stuff with tf before it gets closed.
    
Run Code Online (Sandbox Code Playgroud)

通常,无论何时您在函数中打开文件,都要问问自己是否可以将实际打开推送给调用者并接受类似文件的对象。除了使您的代码更可重用之外,它还使您的代码更易于测试。head不必用实际文件调用:它可以用任何类似文件的对象调用,例如io.StringIO.


换句话说:with语句强制执行建议

如果您打开该文件,您也有责任关闭它。

该建议的对立面

如果您不负责关闭文件,您也不负责打开文件。