python - 如何在 python 中可靠地进行清理?

标签 python ctypes cyclic-reference

我有一些 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/

相关文章:

java - 如何从具有循环关系的数据集中形成一棵树?

python - 高斯噪声没有覆盖主图像-Python

python - 从 Python 运行 Scrapy

windows - 如何使用 Python 2.7.3 更改 Windows 背景

Python Ctypes 键盘事件

c++ - 使用 shared_ptr 和 weak_ptr 时避免间接循环引用

python - 在Excel中插入日期公式得到#name?用python插入后出错

python - 将列表值插入不同的行,同时保留其他列的最新值

python - 在 cython 函数中使用 python ctypes 数组数据

c++ - shared_ptr 和循环引用