Я не уверен, что есть явный / официальный способ добиться этого.Тем не менее, вы можете добавить глобальную переменную, которая будет уничтожена при освобождении модуля cython:
# foo.pyx:
class Observer:
def __init__(self):
print("module initialized")
def __del__(self):
print ("module deleted")
_o=Observer()
Тем не менее, его цитонизация через cythonize foo.pyx -i
не приведет к желаемому эффекту:
[$] python -c `import foo`
module initialized
нет "удаленного модуля", напечатанного на консоли!
Проблема: в любом случае невозможно перезагрузить расширение Cython (например, через importlib.reload()
), поэтому оно освобождается только когда Pythonпереводчик выключенНо тогда нет необходимости освобождать ресурсы ...
Cython хранит все глобальные Python-переменные в глобальной C-переменной, которая называется static PyObject *__pyx_d;
в цитонизированном C-источнике;это просто Python-словарь.Однако, поскольку в этом не уничтоженном словаре есть ссылка на глобальный _o
, счетчик ссылок _o
никогда не станет равным 0, поэтому объект не будет уничтожен.
При установке generate_cleanup_code=True
можно заставить Cython сгенерировать функцию очистки, которая будет помещена в m_free
-слот структуры определения PyModuleDef .Например, со следующим файлом установки:
from distutils.core import setup
from Cython.Build import cythonize
from Cython.Compiler import Options
Options.generate_cleanup_code = True # this is important!
setup(
name = "foo",
ext_modules = cythonize("foo.pyx"),
)
А теперь после python setup.py build_ext -i
:
[$] python -c "import foo"
module initialized
module deleted
он работает как положено.
Потому что тамне равен reload
для расширений Cython, «удаленный модуль» будет виден только при вызове module_dealloc
.
Однако, когда первый листинг был чисто Python, мы бытакже смотрите module deleted
, если importlib.reload(foo)
были вызваны.В этом случае «module_dealloc» не используется, но все ссылки на глобальные _o
будут очищены, а объект будет уничтожен.
В зависимости от того, что нужно, это может быть как ожидаемое, так и неожиданное поведение.