为什么我在__del__中收到"NameError:全局名称'打开'未定义"?

use*_*184 15 python

我在类的__del__函数中得到一个NameError.我不明白为什么在函数__del__中无法访问'open'.我使用的是Python 3.4.0

Python代码:

class Contoller:

    ...

    def __del__(self):
        store = {}
        ...
        pickle.dump(store, open('data.p', 'wb'))    

class MyWindow(Gtk.Window):

    def __init__(self):
        ...
        self.controller = Contoller(self)
        ...
        self.connect("delete-event", self.quit)
        ...

    ...

    def quit(self, widget, event):
        del self.controller
        Gtk.main_quit()
Run Code Online (Sandbox Code Playgroud)

错误信息:

Traceback (most recent call last):
  File "main.py", line 69, in __del__
NameError: name 'open' is not defined
Run Code Online (Sandbox Code Playgroud)

Qui*_*p11 8

user3595184代码在Python 3.4之前一直有效.我知道,因为我刚遇到同样的问题,open()在内部打电话__del__.显然,内置函数不再有效,因为__del__在解释器关闭时运行的时间会发生变化.

更新: 请参阅https://docs.python.org/3/library/weakref.html,尤其是关于终结器的部分.我有几个类封装了对资源的访问,这些资源只要__del__()应用程序退出就会有解锁或清理的方法,无论出于何种原因.在应用程序级别捕获所有异常或退出并明确调用清理方法是不方便且容易出错的.我会尝试使用本地finalizer代替.

更新: 我有更好的运气__enter__()__exit__(),把顶层对象的with条款.至少看起来__exit__()无论如何调用,所以我可以调用__exit__()所有下级对象的清理方法(自己).这对我有用.


ant*_*ont 4

__del__一般来说,依赖Python 中的任何东西都不是一个好主意。

最好使用正常的方法并命名它,self.controller.store()或者任何您认为最好的名称。

相关讨论例如在我不明白这个 python __del__ 行为

更新:atexit.register 可能是您想要的,https://docs.python.org/2/library/atexit.html。正如这篇好文章“常见错误#10:滥用__del__方法”中所述http://www.toptal.com/python/top-10-mistakes-that-python-programmers-make

至于解释,这个讨论告诉我们:“在解释器关闭时,在模块本身被释放之前,模块的全局变量被设置为 None 。” ——也许这也适用于内置函数,http://bugs.python.org/issue5099