__del__是不可靠的,但如果我尝试使用上下文管理器,则该对象不会持久存在

Rig*_*reM 1 python with-statement del resource-cleanup contextmanager

我有一个脚本,实例化了许多子对象.当脚本(和这些对象)结束时......对象需要做一些清理(尤其是临时文件关闭和删除).

我一直在阅读如何__del__不可靠 - 但是上下文管理似乎不起作用,子对象不会持久.他们需要四处闲逛(做文件读写等事情)

一个例子:

WRITER.PY

import os

class Writer(object):
    def __init__(self, filename):
        self.filename = filename
        self.open()

    def open(self):
        self.fh = open(self.filename, "w+", 0)

    def write(self, msg):
        print >>self.fh, str(msg)

    def close(self):
        self.fh.close()
        os.remove(self.filename)

    def __enter__(self):
        print "entered"
#         self.open()


    def __exit__(self, type, value, traceback):
        print "__exit__"
        self.close()
Run Code Online (Sandbox Code Playgroud)

MAIN.PY

def myfunc(filename):
    with WRITER.Writer(filename) as writeit:
        # do some stuff
        writeit.write("hallo")
        # do some more stuff
        writeit.write("more results")
        # even more stuff
        writeit.write("goodbye")
Run Code Online (Sandbox Code Playgroud)

但是当我运行时myfunc(),对象一旦完成就会被垃圾收集__init__().它直接从enter到exit并且在with语句之后不执行任何任务.如果我把开放放入__init__或者开放,似乎并不重要__enter__.

OUTPUT:

Traceback (most recent call last):
  File "/shared/GitHub/Tesera/MRAT_Refactor/bin/MAIN.py", line 13, in <module>
    myfunc("./tempfile")
  File "/shared/GitHub/Tesera/MRAT_Refactor/bin/MAIN.py", line 6, in myfunc
    writeit.write("hallo")
AttributeError: 'NoneType' object has no attribute 'write'
entered
__exit__            
Run Code Online (Sandbox Code Playgroud)

有没有办法以这种方式使用上下文管理器,更好的使用方式__del__......还是有第三种选择来实现这一目标?

Bre*_*arn 8

这个问题与垃圾收集无关.如文档所述,该as子句绑定方法的返回值__enter__.你没有返回任何东西,所以你得到无.

如果要Writer返回对象,则需要return self__enter__方法结束时执行.