Удаление объекта в бесконечном цикле Tkinter

У меня есть следующий код:

from tkinter import *
root = Tk()
class Example:
    var = 1
    def function(self):
        Example.var += 1
    print(Example.var)
    root.after(10,self.function)
Test = Example()
Test.function()
del Test
root.mainloop()

Когда я удаляю объект, переменная var продолжает выводиться. Я понимаю, что это из-за того, что root запускает бесконечный цикл. Как мне удалить объект полностью?


Ответы (2 шт):

Автор решения: Xander
  1. У вас var - атрибут Example, а не атрибут объекта Test. Объект-то вы удаляете, но класс остаётся, а var лежит в нём. (кстати, не стоит называть экземпляры класса именами с большой буквы, в питоне существуют чёткие рекомендации к именованию, которых стоит придерживаться)

  2. Даже если сделать var атрибутом объекта, либо удалять вместе с объектом и класс, это не поможет - так как var используется в function, она не может удалиться окончательно, пока не удалится function. А та не может удалиться, пока существует root

  3. А вообще - что вы пытаетесь сделать? Вы хотите удалить переменную, которая у вас продолжает использоваться в основном цикле root? Вам не кажется, что тут вы что-то странное делаете? Вообще, как показывает практика, в прикладном коде почти никогда нет потребности использовать del. Если вы начинаете явно удалять объекты, то в большинстве случаев это обозначает, что вам стоит пересмотреть саму структуру кода.

→ Ссылка
Автор решения: gil9red

Немного переписал код.

Необходимости ручного удаления действительно обычно нет, достаточно чтобы ссылки на объект достигли 0, тогда тот будет удален сборщиком мусора. Например, тут test = Example() объект типа Example имеют 1 ссылку, в переменной test, а после test = None счетчик ссылок будет 0.

Чтобы остановить тот цикл добавил поле объекта, чтобы индивидуально для каждого объекта можно было остановить.

Пример:

from tkinter import *
root = Tk()

class Example:
    var = 1

    def __init__(self):
        self.is_run = True

    def function(self):
        Example.var += 1
        print(Example.var)
        if self.is_run:
            root.after(10, self.function)

test = Example()
test.function()
test.is_run = False
test = None

root.mainloop()
→ Ссылка