funktionen definieren: def vs. lambda (newbee)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Dienstag 29. Mai 2007, 11:59

Genau, bei Tkinter Buttons ist Lambda sehr praktisch.
Speziell, wenn mann einen Schwung an Knöpfen generieren möchte.
Soll an diese Knöpfe dann eine Funktion gebunden werden, deren Verhalten sich auf Grund von Übergabeparametern unterscheiden soll wüsste ich im Moment keinen andere Möglichkeit.

Im unteren Beispiel habe ich einen Auszug aus einem aktuellen Projekt.
Mit dieser Funktion kann im "try" Block eine Funktion an die Knöpfe gebunden werden, die sich durch Übergabeparameter von Knopf zu Knopf unterscheidet.
(Hier: einem markiertem Text wird am Anfang und am Ende mit Textzeichen erweitert, jeder Knopf fügt unterschiedliche Textzeichen hinzu.)

Ich wüste nicht, wie ich das ohne lambda hinbekommen würde.


Code: Alles auswählen

    def label_button_row(self, parent_widget=None,
                            btnlst=None, start_count=0):
        """Build a 2 column table with a label beside each button in a row.
        Bind a keyboard sequence to the button command.
        Display this keyboard sequence on the label.

        todo:
            - think about a parameter for the widget to bind the Hotkeys
            - rename to: labled_button_row, draw_labled_button_row

        Parameter:
        --> parent_widget:
                Parent widget to place the table

        --> btnlst:
                Type: List of dicts representing a button
                Example:
                    {'text':'**bold**',     # displayed on the Button (string)
                    'cmd':self.on_tag_insert,   # command
                    'open_tag':'**',        # chars representing the beginning
                                            # of a tag for inserting (string)
                    'close_tag':'**',       # chars representing the end
                                            # of a tag for inserting (string)
                    'keytxt':'CTRL+b',      # displayed on the Label (string)
                    'hotkey':'<Control-b>'} # keyboard sequence (string)
                Note:
                    The existence of 'open_tag' and 'close_tag' in btnlst
                    decides which command is bound to the Button.
                    If they aren't there 'cmd' must be a function without
                    parameters!!!
                    otherwise 'cmd' needs following parameters:
                        otag = btn['open_tag']
                        ctag = btn['close_tag']
                        event = None  # Placeholder for a keysequence

        --> start_count:
                Type: int

                Description:
                    The table is relized with tkinter grid layout manager.
                    start_count is used if there is already a grid
                    (with a Label beside a button).
                    start_count can add the automatic genrated
                    buttons under the existing.
                    In Wombat_Editor it is used to put a label_button_row
                    under a Tkinter menubutton(file choose, headlines).
        """
        i = start_count
        for btn in btnlst:
            try:
                otag = btn['open_tag']
                ctag = btn['close_tag']
                event = None
                doit = lambda e=event, o=otag, c=ctag:self.on_tag_insert(e,o,c)
                tk.Button(parent_widget, text=btn['text'], command=doit,
                        relief=tk.RIDGE
                        ).grid(column=0, row=i, sticky=tk.W+tk.E)
                self.text.bind(btn['hotkey'],doit)
            except KeyError:
                # generate buttons with an unique command  for every button
                tk.Button(parent_widget, text=btn['text'], command=btn['cmd'],
                        relief=tk.RIDGE
                        ).grid(column=0, row=i, sticky=tk.W+tk.E)
            tk.Label(parent_widget, text=btn['keytxt'], relief=tk.FLAT
                ).grid(column=1, row=i, sticky=tk.W)
            i +=1
Zuletzt geändert von Mr_Snede am Dienstag 29. Mai 2007, 12:04, insgesamt 1-mal geändert.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 29. Mai 2007, 12:03

Wie oft soll ich denn noch erklären, dass man *jede* Benutzung von `lambda` mit einer `def`-Konstruktion ersetzen kann.

Gerade in deinem Beispiel weist du ja die Lambdafunktion gerade einem Namen zu.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Beitragvon Mr_Snede » Dienstag 29. Mai 2007, 12:09

Och menno, warum ist mir das nicht selbst aufgefallen.
Peinlich, peinlich
- aber danke für den Schlag auf den Hinterkopf - hatte ich wohl nötig.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], Torsten_K