Tkinter .withdraw() странное поведение

#python #python-2.7 #tkinter

#питон #python-2.7 #tkinter #python

Вопрос:

Используя следующий код, корневое окно Tkinter будет скрыто:

 def main():
    root = Tkinter.Tk()
    root.iconify()
    a = open(tkFileDialog.askopenfilename(), 'r')

main()
  

Однако, используя этот вариант, корневое окно не будет скрыто:

 class Comparison:
    def __init__(self, file=open(tkFileDialog.askopenfilename(),'r')):
        self.file = file
        self.length = sum(1 for _ in self.file)

def main():
    root = Tkinter.Tk()
    root.iconify()
    a = Comparison()

main()
  

Почему вызов tkFileDialog.askopenfilename с помощью конструктора вызывает такое поведение? Я пробовал оба root.withdraw() root.iconify() и испытывал то же самое поведение.

Возможно, стоит отметить, что я использую OSX 10.11.6.

Спасибо!

Ответ №1:

Когда вы делаете это:

 def __init__(self, file=open(tkFileDialog.askopenfilename(),'r')):
  

Это выполняется немедленно open(tkFileDialog.askopenfilename(),'r') , потому что аргументы по умолчанию вычисляются при определении функции. Поэтому, когда вы запускаете второй блок кода, интерпретатор создает необходимое корневое окно Tkinter и открывает это средство выбора файлов, пока оно все еще определяет этот класс. После этого вы определяете функцию main . Наконец, вы вызываете main() , который создает корневой объект, удаляет его и создает экземпляр объекта Comparison класса. Корневое окно, которое вы явно создали, root = Tkinter.Tk() скрыто. Однако более старого, который Python был вынужден создать для существования диалогового окна file, не было.

Чтобы исправить это, поместите поведение по умолчанию в тело метода, а не в его подпись:

 class Comparison:
    def __init__(self, file=None):
        if file is None:
            self.file = open(tkFileDialog.askopenfilename(),'r')
        else:
            self.file = file
        self.length = sum(1 for _ in self.file)