Python ctypes.CDLL在sys.exit时的对象销毁顺序

Python ctypes.CDLL在sys.exit时的对象销毁顺序,python,garbage-collection,ctypes,z3,Python,Garbage Collection,Ctypes,Z3,我目前面临一个CDLL对象的问题,该对象在仍然需要时消失。下面的代码将我的DLL加载到全局_lib(出于好奇,它是),声明一些DLL函数,然后创建一个Ctx对象,该对象在其构造函数和析构函数中调用CDLL import sys, os, ctypes class NC(ctypes.c_void_p): def __init__(self, c): self._as_parameter_ = c _lib = ctypes.CDLL(os.path.join(os.path.realpa

我目前面临一个CDLL对象的问题,该对象在仍然需要时消失。下面的代码将我的DLL加载到全局
_lib
(出于好奇,它是),声明一些DLL函数,然后创建一个Ctx对象,该对象在其构造函数和析构函数中调用CDLL

import sys, os, ctypes

class NC(ctypes.c_void_p):
  def __init__(self, c): self._as_parameter_ = c

_lib = ctypes.CDLL(os.path.join(os.path.realpath('.'), 'libz3.dll'))
_lib.Z3_mk_context_rc.restype = NC
_lib.Z3_mk_context_rc.argtypes = [ctypes.c_void_p]
_lib.Z3_del_context.argtypes = [NC]

class Ctx:
    def __init__(self):
        global _lib
        # self.lib = _lib
        self.nctx = _lib.Z3_mk_context_rc(0)
        assert _lib is not None, "in Ctx.__init__"

    def __del__(self):
        global _lib
        assert _lib is not None, "in Ctx.__del__" # fails frequently
        _lib.Z3_del_context(self.nctx)
        # self.lib = None

c = Ctx()
assert _lib is not None, "global"
sys.exit(1)
我所经历的症状是,
Ctx.\uu del\uu
中的断言经常失败(但并不总是),而其他断言则从未失败过。如果在
Ctx.lib
中保留对
\u lib
的引用,也会出现这种情况

在本例中,通过友好地删除
c
(例如
delc
c=None
,或将其包装在
with
语句中,症状很容易修复。然而,总的来说,这些解决方案都不令人满意,因为libz3.dll的用户不能总是在Python的GC启动之前很好地清理所有对象


有没有办法告诉Python不要将
\u lib
设置为
None
,除非它真的不再需要了

通常会将对
\u lib
或函数的引用存储为默认参数,例如
def\u del\u(self,Z3\u del\u context=\u lib.Z3\u del\u context)
。如果不重新绑定变量,则不必将其声明为
全局
。如果名称不是本地指定的,编译器会将其分类为全局名称。谢谢,这是一个有趣的想法!它适用于这个小例子,我认为它可能很容易在更大范围内应用。