【问题标题】:Closing a file in Class __exit__ or __del__ method?在类 __exit__ 或 __del__ 方法中关闭文件?
【发布时间】:2014-10-24 18:52:49
【问题描述】:

我想编写一个能够编写 html 文件的类。我现在有以下骨架:

class ColorWheel(object):
    def __init__(self, params):
        self.params = params

    def __enter__(self):
        self.f = open('color_wheel.html', 'w')
        self._write_header()
        return self

    def __exit__(self, type_unused, value_unused, traceback_unused):
        self._write_footer()
        self.f.close()

    def wheel(self):
        # Code here to write the body of the html file
        self.f.write('BODY HERE')

我使用这个类:

with ColorWheel(params) as cw:
    cw.wheel()

文件完全按照我的预期编写。但是,当我运行它时,我收到以下错误:

Exception ValueError: 'I/O operation on closed file' in <bound method ColorWheel.__del__ of ColorWheel.ColorWheel object at 0x0456A330>> ignored

我假设它正在尝试关闭已经关闭的文件。它是否正确?如果是这样,关闭文件的正确方法是什么?

【问题讨论】:

  • 有一个__del__方法,不是吗。
  • 你在with之外有for吗?
  • @Kasra:这有什么关系?
  • 我在打开文件with 时看到此错误,然后不要在with 中写入其他部分代码

标签: python file-io destructor


【解决方案1】:

您还有一个__del__ 方法试图在关闭文件后写入 到文件。当cw 超出范围并被清理时,__del__ 挂钩被调用,此时您似乎正在尝试写入文件。

您可以测试文件是否已经关闭:

if not self.f.closed:
    # do something with file

【讨论】:

  • 答案是正确的。我想添加对您应该阅读的官方文档的引用,以便理解 with 语句:docs.python.org/3.4/reference/…
  • 我以为我没有 del 方法,但事实证明我有,因为我继承自另一个类。我没有在上面显示,我认为这无关紧要。现在一切都说得通了。
  • 是否保证一旦对象超出范围就会调用__del__?还是依赖于实现?
  • @Sylvain:这取决于实现。 CPython 使用引用计数,并立即调用 __del__。但 IronPython 和 Jython 使用垃圾回收方案,调用会延迟。
  • @Martijn 关于 Jython:由于 JVM 不保证在程序终止时甚至调用 finalize(),这是否意味着甚至可能不会调用 __del__?我无法通过谷歌搜索找到最新版本的 Jython 的明确答案...
猜你喜欢
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2020-09-16
  • 2016-06-26
  • 1970-01-01
相关资源
最近更新 更多