У меня есть класс, объекты которого используют системные ресурсы (например, создавая временные файлы), которые необходимо очистить. По крайней мере, это должно произойти, когда программа закончится. До сих пор я использую contextmanager
сделать это, напримерОбеспечить выпуск ресурсов в интерактивном сеансе
@contextlib.contextmanager
def tempdir(prefix='tmp'):
tmpdir = tempfile.mkdtemp(prefix=prefix)
try:
yield tmpdir
finally:
shutil.rmtree(tmpdir)
with tempdir() as tmp:
do_something(tmp)
Это гарантирует, что ресурсы будут освобождены, как только я закончу с ними, и это хорошо работает для большинства моих целей. Тем не менее, я нахожу, что эта модель ломается при использовании python в интерактивном режиме, например, в ipython
. В этом случае весь сеанс должен находиться внутри блока with
, что не очень практично (фактически, ipython
будет оценивать только блоки сразу, поэтому вся интерактивность исчезнет).
Есть ли способ обеспечить очистку ресурсов, оставаясь при этом доступным для использования в интерактивных сеансах? В C++
это может быть достигнуто путем помещения очистки в деструктор. Оператор python __del__
похож, но мне сказали, что __del__
является ненадежным и его следует избегать. В частности, это it is not guaranteed that __del__
will be called for objects that still exist when the interpreter exits .. Это один из случаев, когда __del__
по-прежнему является лучшим решением? И если подход contextmanager
несовместим с интерактивными сеансами, почему он рекомендуется как самый «питонический» подход?