Как заменить лямбда-обработчики обратных вызовов на вызываемые обработчики объектов класса? - PullRequest
0 голосов
/ 02 мая 2020

Мой следующий вопрос относится к примеру 8-10 из Программирование Python, 4-е издание, автор Марк Лутц. Пример о создании панели простых кнопок, которые запускают демонстрации диалогов и возвращают значения этих диалоговых вызовов в stdout .

Таблица диалога выглядит следующим образом:

#dialogTable.py

from tkinter.filedialog     import askopenfilename
from tkinter.colorchooser   import askcolor
from tkinter.messagebox     import askquestion, showerror
from tkinter.simpledialog   import askfloat

demos = {
    'Open': askopenfilename,
    'Color': askcolor,
    'Query': lambda: askquestion('Warning', 'You typed "rm *"\nConfirm?'),
    'Error': lambda: showerror('Error!', "He's dead, Jim"),
    'Input': lambda: askfloat('Entry', 'Enter credit card number')
}

Код ниже создает панель кнопок и делает их функциональными. Мой вопрос относится к этой части:

from tkinter import *
from dialogTable import demos       # button callback handlers
from quitter import Quitter         # attach a quit object to me

class Demo(Frame):
    def __init__(self, parent=None, **options):
        Frame.__init__(self, parent)
        self.pack()
        Label(self, text="Basic demos").pack()
        for key in demos:
            func = (lambda key=key: self.printit(key))
            Button(self, text=key, command=func).pack(side=TOP, fill=BOTH)
        Quitter(self).pack(side=TOP, fill=BOTH)

    def printit(self, name):
        print(name, 'returns =>', demos[name]())    # fetch, call, print

if __name__ == '__main__': Demo().mainloop()

Quitter - это просто класс для кнопки quit .

Мой вопрос - как мне переписать этот код, чтобы использовать вызываемый объект класса (__call__) вместо лямбда для отсрочки вызова фактического обработчика?

1 Ответ

1 голос
/ 02 мая 2020

Ну, в этом случае, вы могли бы сделать что-то с эффектом:

from tkinter import *
from dialogTable import demos       # button callback handlers
from quitter import Quitter         # attach a quit object to me

class Wrapper:
    def __init__(self, func, key):
        self.func = func
        self.key = key
    def __call__(self):
        return self.func(self.key)

class Demo(Frame):
    def __init__(self, parent=None, **options):
        Frame.__init__(self, parent)
        self.pack()
        Label(self, text="Basic demos").pack()
        for key in demos:
            func = Wrapper(self.printit, key)
            Button(self, text=key, command=func).pack(side=TOP, fill=BOTH)
        Quitter(self).pack(side=TOP, fill=BOTH)

    def printit(self, name):
        print(name, 'returns =>', demos[name]())    # fetch, call, print

if __name__ == '__main__': Demo().mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...