我有一些 ctypes 绑定(bind),对于每个 body.New 我应该调用 body.Free。我绑定(bind)的库没有与其余代码隔离的分配例程(它们可以在那里的任何地方调用),并且为了使用一些有用的功能,我需要进行循环引用。
我认为,如果我找到一种可靠的方法将析构函数挂接到对象,它就会解决。 (如果弱引用能在数据被丢弃之前给我回调的话会有所帮助。
很明显,当我输入 velocity_func 时,这段代码会失败:
class Body(object):
def __init__(self, mass, inertia):
self._body = body.New(mass, inertia)
def __del__(self):
print '__del__ %r' % self
if body:
body.Free(self._body)
...
def set_velocity_func(self, func):
self._body.contents.velocity_func = ctypes_wrapping(func)
我也尝试通过 weakrefs 来解决它,这些事情似乎变得更糟,只是在很大程度上更加不可预测。
即使我不输入 velocity_func,至少在我这样做时会出现循环:
class Toy(object):
def __init__(self, body):
self.body.owner = self
...
def collision(a, b, contacts):
whatever(a.body.owner)
那么如何确保结构将被垃圾回收,即使它们是由共享库分配/释放的?
如果你对更多细节感兴趣,这里有存储库:http://bitbucket.org/cheery/ctypes-chipmunk/
最佳答案
你想做的,即创建一个分配东西的对象,然后在对象不再使用时自动释放,不幸的是,这在 Python 中几乎是不可能的。不能保证调用 del 语句,因此您不能依赖它。
Python 中的标准方法很简单:
try:
allocate()
dostuff()
finally:
cleanup()
或者从 2.5 开始,您还可以创建上下文管理器并使用 with 语句,这是一种更简洁的方法。
但是这两个主要用于当您在代码片段的开头分配/锁定时。如果你想为程序的整个运行分配资源,你需要在启动时分配资源,在程序的主要代码运行之前,然后释放。这里没有涉及一种情况,那就是当您想要动态分配和释放许多资源并在代码中的许多地方使用它们时。例如,您想要一个内存缓冲区或类似的池。但大多数情况都是针对内存的,Python 会为你处理,所以你不必为这些操心。当然,在某些情况下,您希望对非内存的事物进行动态池分配,然后您希望在您的示例中尝试的释放类型,而这用 Python 做起来很棘手.
关于python - 如何在 python 中可靠地进行清理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1044073/