File io 处理文件的类或方法是否应该作为副作用关闭文件?

File io 处理文件的类或方法是否应该作为副作用关闭文件?,file-io,python,File Io,Python,我想知道编写处理文件的方法时,哪种方法更“Pythonic”/更好。处理文件的方法是否应该作为副作用关闭该文件?数据是“文件”的概念是否应该从处理数据的方法中完全抽象出来,这意味着它应该期望一些“流”,但不一定是文件 例如,可以这样做吗: process(open('somefile','r')) ... carry on 其中process()关闭文件句柄: def process(somefile): # do some stuff with somefile somefi

我想知道编写处理文件的方法时,哪种方法更“Pythonic”/更好。处理文件的方法是否应该作为副作用关闭该文件?数据是“文件”的概念是否应该从处理数据的方法中完全抽象出来,这意味着它应该期望一些“流”,但不一定是文件

例如,可以这样做吗:

process(open('somefile','r'))
... carry on
其中
process()
关闭文件句柄:

def process(somefile):
    # do some stuff with somefile
    somefile.close()
还是这样更好:

file = open('somefile','r')
process(file)
file.close()

值得一提的是,我通常使用Python来编写相对简单的脚本,这些脚本的目的非常明确,我可能是唯一一个使用它们的人。这就是说,我不想教自己任何不好的做法,我宁愿学习做事情的最佳方式,因为即使是一件小事也值得做好

一般来说,打开文件的人最好关闭文件。在你的问题中,第二个例子更好

这是为了防止可能的混淆和无效操作

编辑:如果实际代码并不比示例代码复杂,那么最好让process()打开并关闭该文件,因为调用者不会将该文件用于任何其他用途。只需传入文件的路径/名称。但是,如果可以想象process()的调用者会在关闭文件之前使用该文件,那么将文件保持打开状态,并在process()之外关闭操作。
一起使用意味着不必担心这一点


至少,不是在2.5+上。

否,因为它降低了灵活性:如果函数不关闭文件,而调用方不需要它,则调用方可以关闭文件。若确实如此,但调用者仍然需要打开文件—调用者坚持使用StringIO或其他方法重新打开文件

此外,关闭文件对象还需要对其真实类型进行额外的假设(对象可以支持.read()或.write(),但没有有意义的.close()),这会妨碍duck类型


对于CPython来说,保持打开状态的文件不是问题——它将在垃圾收集后立即关闭(open('somefile'))。(其他实现也将gc并关闭文件,但在未指定的时刻)

因此,为了与
保持一致,不要将文件作为副作用关闭。而且,这与
更加一致-1:在执行实际工作的处理函数中打开和关闭文件很少“更好”。当您假定一个
文件
时,您会限制重用。您应该始终假设一个“类似文件的对象”,并将
打开
关闭
作为一项与处理完全分离的责任推到一旁。@S.Lott:在考虑了一会儿之后,我同意您的看法。重新编辑。谢谢系统的其余部分是什么样子的?您是否试图打开一个文件并在其上运行多个“进程”?在您的简单示例中,传递打开的文件然后关闭它是没有意义的。。。该过程还可以打开和关闭该文件。