【问题标题】:Why can you close() a file object more than once?为什么你可以多次关闭()一个文件对象?
【发布时间】:2016-09-20 17:58:19
【问题描述】:

这个问题纯粹是出于好奇。在最近的一个问题 here 的讨论中提出,我经常想知道为什么当人们通过误解明确关闭文件时,上下文管理器 (with) 不会引发错误......然后我发现你即使不使用with,也可以在文件上多次调用close()而不会出错。

我们能找到与此相关的唯一内容是here,它只是温和地说(强调我的):

关闭( )
关闭文件。已关闭的文件无法再读取或写入。任何需要打开文件的操作都会在文件关闭后引发 ValueError。 允许多次调用 close()

这似乎是有意为之,但是,如果您无法对已关闭的文件执行任何操作,那么我们就无法弄清楚为什么允许多次关闭文件。有用例吗?

【问题讨论】:

  • 也许如果代码有点草率,并且在多个地方有close(),而不是全程跟踪文件的状态……至少你的代码不会抛出异常。跨度>
  • 哈!你打败了我!我正在编写一个几乎相同的问题,只是看到这个问题作为一个相关问题弹出。我会赞成;)
  • @elethan 我正要在另一个线程中给你发消息:P
  • 有时它使代码更容易一些。另外,如果你有一个实际的错误,你 close 一个文件然后再次使用它其他操作已经触发异常。所以在那里触发它真的没有意义。

标签: python


【解决方案1】:
  1. 考虑with 是错误的。这种行为在 Python 中一直存在永远,因此值得保留它以实现向后兼容性。

  2. 因为引发异常没有任何意义。如果您的代码中存在实际错误,您可能会在完成使用之前关闭文件,那么在使用 readwrite 操作时无论如何都会遇到异常,因此您将永远无法到达第二次调用close.

  3. 允许这样做很少使代码更容易编写,避免添加大量 if not the_file.isclosed(): the_file.close()

  4. BDFL 以这种方式设计文件对象,但我们坚持这种行为,因为没有充分的理由去改变它。

【讨论】:

  • the_file.closed ;)
  • 文件的幂等关闭只是一个好主意。由于多次调用 close()不是错误,因此程序员在清理资源时会变得更加积极。正如@Bakuriu 所提到的,在关闭之前检查文件是否已关闭(以避免错误)只会使代码复杂化并让程序员感到烦恼。
【解决方案2】:

资源管理很重要。这也是我们首先拥有上下文管理器的部分原因。

猜测核心开发团队认为最好让 close 多次调用“安全”以鼓励人们关闭他们的文件。否则,您可能会让自己陷入询问“这之前是否关闭过?”的情况。如果不能多次调用.close(),唯一的选择是将您的file.close() 调用放在try/except 子句中。这使得代码更丑陋,而且(坦率地说)很多人可能会删除对file.close() 的调用,而不是正确处理它。在这种情况下,可以很方便地拨打file.close() 而不必担心任何后果,因为它几乎可以肯定会成功并留下一个您知道之后已关闭的文件。

【讨论】:

    【解决方案3】:

    函数调用实现了它的承诺 - 在调用它之后文件关闭。这不像是什么失败,只是你根本不需要做任何事情来确保我们要求的条件。

    【讨论】:

    • 我不确定我是否理解这个答案。我问的更多是在已经关闭的东西上调用close() 通常会导致异常,但在关闭的文件对象的情况下不会
    • @roganjosh 是吗?如果 dict 已经为空(因为“没有什么要清除的”),dict_instance.clear() 是否应该引发异常?函数调用后实例将为空,这就是调用者所要求的。有时什么都不做就足以使测试通过。另外,通常会导致异常,您的来源是什么?
    • 我不确定这是怎么回事,其他答案很清楚。尝试在与 sqlite3 数据库的已关闭连接上关闭游标。你是说除了第二次对close() 之外的closed 对象做nothing 的情况并不少见?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多