为什么我得到" NameError:全球名称'打开'没有定义"在__del__?

时间:2014-05-02 06:35:49

标签: python

我在一个类的__del__函数中得到一个NameError。我不明白为什么打开'在函数__del__中无法访问。我使用的是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()

错误讯息:

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

3 个答案:

答案 0 :(得分:7)

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

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

<强>更新 我对__enter__()__exit__()有更好的运气,将顶级对象放在with子句中。看起来至少__exit__()被调用,无论如何,所以我可以调用所有从属对象的清理方法(__exit__()&#39; s)。这对我有用。

答案 1 :(得分:2)

在Python中依赖__del__通常不是一个好主意。

更好地使用常规方法并调用它,self.controller.store()或您认为最佳的名称。

相关讨论例如在I don't understand this python __del__ behaviour

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

至于解释,这个讨论告诉:&#34;在解释器关闭时,模块的全局变量在模块本身被释放之前被设置为None。&#34; - 也许这也适用于内置,http://bugs.python.org/issue5099

答案 2 :(得分:-2)

我认为这只是一个范围问题。

self.controller = Contoller(self)

我不知道为什么在启动Controller类时应该将MyWindow类作为参数传递。尝试将其更改为:

self.controller = Contoller()