Существует конкретный пример того, когда вы должны использовать del
(могут быть и другие, но я знаю об этом один раз), когда вы используете sys.exc_info()
для проверки исключения. Эта функция возвращает кортеж, тип возникшего исключения, сообщение и трассировку.
Первые два значения обычно достаточны для диагностики ошибки и воздействия на нее, но третье содержит весь стек вызовов между местом возникновения исключения и местом его обнаружения. В частности, если вы делаете что-то вроде
try:
do_evil()
except:
exc_type, exc_value, tb = sys.exc_info()
if something(exc_value):
raise
traceback, tb
заканчивается в локальных элементах стека вызовов, создавая циклическую ссылку, которая не может быть собрана сборщиком мусора. Таким образом, важно сделать:
try:
do_evil()
except:
exc_type, exc_value, tb = sys.exc_info()
del tb
if something(exc_value):
raise
чтобы разорвать круговую ссылку. Во многих случаях, когда вы захотите вызвать sys.exc_info()
, как в случае с магией метаклассов, трассировка полезна , поэтому вы должны убедиться, что вы ее очистили, прежде чем сможете оставить обработчик исключений. Если вам не нужна трассировка, вы должны немедленно удалить ее или просто выполните:
exc_type, exc_value = sys.exc_info()[:2]
Чтобы избежать всего этого вместе.