Python:在程序终止之前通过终结器刷新缓冲区
我保留了一个事务缓存,以便在发生水印或对象终结时刷新(到持久存储)。 由于 __del__
是 不再保证在每个对象上调用,是将类似函数(或 __del__ 本身)挂接到 atexit.register
(在初始化期间)的适当方法吗?
如果我没记错的话,这将导致该方法所绑定的对象一直挂起,直到程序终止。 这不太可能成为问题,但也许有更优雅的解决方案?
注意:我知道使用 __del__
并不理想,因为 它可能会导致无法捕获的异常,但我想不出另一种方法可以在我的程序中完成如此短的级联 finalize()
调用。 蒂亚!
I keep a cache of transactions to flush (to persistent storage) on the event of a watermark or object finalization. Since __del__
is no longer guaranteed to be called on every object, is the appropriate approach to hook a similar function (or __del__
itself) into atexit.register
(during initialization)?
If I'm not mistaken, this will cause the object to which the method is bound to hang around until program termination. This isn't likely to be a problem, but maybe there's a more elegant solution?
Note: I know using __del__
is non-ideal because it can cause uncatchable exceptions, but I can't think of another way to do this short of cascading finalize()
calls all the way through my program. TIA!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您必须处理资源,首选方法是显式调用
close()
或finalize()
方法。 看一下with
语句来抽象它。 在您的情况下,weakref
模块可能是一个选项。 缓存的对象可以由系统进行垃圾收集,并调用它们的 __del__() 方法,或者如果它们仍然存在,您可以最终确定它们。If you have to handle ressources the prefered way is to have an explicit call to a
close()
orfinalize()
method. Have a look at thewith
statement to abstract that. In your case theweakref
module might be an option. The cached object can be garbage collected by the system and have their__del__()
method called or you finalize them if they are still alive.我会说
atexit
或尝试看看是否可以将代码重构为能够使用with_statement
来表达,该语句位于__future__
中默认为 2.5 和 2.6。 2.5 包含一个 contextlib 模块来简化一些事情。 我在使用 Canonical 的 Storm ORM 时做过类似的事情。from future import with_statement
对于非数据库情况,您可以只注册要使用全局刷新的对象,然后使用类似的东西。 这种方法的好处是它使事情保持明确。
I would say
atexit
or try and see if you can refactor the code into being able to be expressed using awith_statement
which is in the__future__
in 2.5 and in 2.6 by default. 2.5 includes a module contextlib to simplify things a bit. I've done something like this when using Canonical's Storm ORM.from future import with_statement
For a non-db case, you could just register the objects to be flushed with a global and then use something similar. The benefit of this approach is that it keeps things explicit.
如果您不需要在执行刷新时使对象处于活动状态,则可以使用 弱引用
这与您提出的解决方案类似,但不是使用真正的引用,而是存储弱引用列表,并使用回调函数来执行刷新。 这样,引用不会使这些对象保持活动状态,并且您不会遇到
__del__
方法的任何循环垃圾问题。如果需要保证在某个时刻完成,您可以在终止时运行弱引用列表,以手动刷新任何仍然活着的弱引用。
If you don't need your object to be alive at the time you perform the flush, you could use weak references
This is similar to your proposed solution, but rather than using a real reference, store a list of weak references, with a callback function to perform the flush. This way, the references aren't going to keep those objects alive, and you won't run into any circular garbage problems with
__del__
methods.You can run through the list of weak references on termination to manually flush any still alive if this needs to be guaranteed done at a certain point.
将以下内容放入名为
destructor.py
的文件中,现在可以这样使用:
Put the following in a file called
destructor.py
now use it this way:
我认为
atexit
是解决这个问题的方法。I think
atexit
is the way to go here.