python docs for tempfile.NamedTemporaryFile 说:



我有一个无法触摸的程序,称为prog input.txt。我想编写一个python函数来给它一个字符串。

这是各种不太奏效的方法:

from tempfile import NamedTemporaryFile

  • 如果在Windows上合法,则不明显
    with NamedTemporaryFile() as f:
        f.write(contents)
        subprocess.check_call(['prog', f.name])  # legal on windows?
    
  • 可能过早删除文件
    with NamedTemporaryFile() as f:
        f.write(contents)
        f.close()  # does this delete the file?
        subprocess.check_call(['prog', f.name])
    
  • 无法正确清理
    with NamedTemporaryFile(delete=False) as f:
        f.write(contents)  # if this fails, we never clean up!
    try:
        subprocess.check_call(['prog', f.name])
    finally:
        os.unlink(f.name)
    
  • 有点难看
    f = NamedTemporaryFile(delete=False)
    try:
        with f:
            f.write(contents)
        subprocess.check_call(['prog', f.name])
    finally:
        os.unlink(f.name)
    

  • 以下哪项是正确的?

    最佳答案

    正如您所怀疑的,前三个变体都被破坏了-第一个变体将在Windows上抛出PermissionError;第二个确实确实过早删除了文件;第三个不能正确处理异常。

    因此,您的第四段代码是正确的方法。

    但是,正如您所说,这有点丑陋。我建议将其包装在一个函数中以提高可读性和可重用性:

    import os
    from contextlib import contextmanager
    from tempfile import NamedTemporaryFile
    
    @contextmanager
    def ClosedNamedTempfile(contents, mode='w'):
        f = NamedTemporaryFile(delete=False, mode=mode)
        try:
            with f:
                f.write(contents)
            yield f.name
        finally:
            os.unlink(f.name)
    

    这使我们可以像这样使用它:
    with ClosedNamedTempfile('foobar\n') as f:
        subprocess.check_call(['prog', f])
    

    10-07 14:58