Как использовать num2date / date2num с Tkinter mainloop ()

#python #tkinter #tail-recursion

#python #tkinter #хвостовая рекурсия

Вопрос:

У меня есть этот код внутри tkinter mainloop() :

 self.raw_start_date = num2date(date2num(dt.datetime.strptime(self.end_date, "%Y-%m-%d")) - self.period)
self.start_date = self.raw_start_date.strftime("%Y-%m-%d")
  

Я получаю следующую ошибку:

Файл «D:Python35-32libtkinter__init__.py «, строка 1949, в getattr возвращает getattr(self.tk , attr) Ошибка рекурсии: превышена максимальная глубина рекурсии

Может кто-нибудь, пожалуйста, помочь с этим?

Комментарии:

1. вы наследуете от виджета tk, но забываете позвонить super().__init__() ?

Ответ №1:

Это артефакт подкласса tkinter.Tk и переопределения __init__ метода без какого-либо вызова Tk.__init__ :

 import tkinter

class Application(tkinter.Tk):
    def __init__(self):
        "do out stuff, forget to call Tk.__init__(self) !"
        pass


app = Application()

app.any_possible_attribute_name #recursion error here
  

Это происходит потому, что:

  1. Tk.__init__ инициализирует очень важный .tk атрибут.
  2. Любой поиск атрибута (который не может быть разрешен) перенаправляется на .tk атрибут.

Поэтому обычно, если вы сделали app.thing и .thing еще не были определены, тогда он попытается вернуться app.tk.thing , но когда app.tk он не определен, он пытается выполнить поиск app.tk.tk , что требует поиска app.tk , что вызывает ошибку рекурсии.


Чтобы исправить это

Просто не забудьте вызвать Tk.__init__(self) свой метод инициализации:

 import tkinter

class Application(tkinter.Tk):
    def __init__(self):
        "do out stuff, just make sure to call Tk.__init__(self) !"
        tkinter.Tk.__init__(self)


app = Application()

app.any_possible_attribute_name
#now we just get an AttributeError