Есть ли какие то варианты вызвать деструктор принудительно кроме обязательного использования контекстного менеджера?

В Python деструкторы не вызываются явно, а управление ими обеспечивается автоматически с помощью сборщика мусора. Однако, есть несколько вариантов, которые позволяют вызвать деструктор объекта принудительно.

1. Принудительная вызов метода __del__: Вы можете вызвать метод __del__ непосредственно, но это не рекомендуется, так как может привести к неопределенному поведению. Метод __del__ будет вызван автоматически при удалении объекта, но вы можете его вызвать вручную, например:

obj = MyClass()
obj.__del__()

2. Использование функции gc.collect(): Функция gc.collect() принудительно запускает сборщик мусора и может привести к вызову деструкторов объектов, которые больше не используются. Однако, использование этой функции также не рекомендуется и должно быть особыми случаями, так как сборка мусора автоматически выполняется самой Python.

import gc

gc.collect()

3. Использование контекстного менеджера: Как вы упомянули в вашем вопросе, наиболее рекомендуемый способ вызвать деструктор объекта – использовать контекстный менеджер. Это гарантирует, что деструктор будет вызван, когда объект выходит за пределы контекста. Например:

class MyClass:
    def __init__(self):
        pass
     
    def __enter__(self):
        return self
     
    def __exit__(self, exc_type, exc_value, traceback):
        self.__del__()

# Использование контекстного менеджера
with MyClass():
    # Ваш код

Важно отметить, что во всех вышеперечисленных способах вызов деструктора является нетипичным и может привести к нестабильности программы. В большинстве случаев Python автоматически управляет выделением и освобождением памяти, поэтому нет необходимости вызывать деструкторы вручную.