callback Beispiel

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.
Antworten
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Hallo zusammen
Ich versuche mir zu erklären, was ein callback bringt. Ich lese im Buch "Rapid Gui Programming with Python and Qt" von Summerfield (p. 63) folgendes:
"... In the simplest case we want to store a function (i.e. an object reference to a function) that we can then call later. A function stored like this is known as a callback. Example:

Code: Alles auswählen

def hello(who):
    print "Hello", who

def goodbye(who):
    "Goodbye", who

funclist = [hello, goodbye]
# Some time later
for func in funclist:
    func("me")
Here we have stored two functions and called them later on."

Er sagt, der Parameter "me" ist schon bekannt, ok das ist gut, man weiss schon von Anfang an, dass "me" übergeben werden soll. Aber was bringt die funclist? Wieso kann man nicht einfach die Funktion, die benötigt wird, aufrufen, sondern lässt eine Referenz darauf in einer Liste?

Wäre froh um Hinweise.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Wieso kann man nicht einfach die Funktion, die benötigt wird, aufrufen[...]
Meistens weil man nicht weiß welche Funktion aufgerufen werden soll: ein (häufig verwendetes) Beispiel wäre das `key` Argument von sorted() bzw. list.sort() oder die Event-handler der GUI-Frameworks.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ein Callback ist nichts anderes als ein Zeiger auf eine Funktion. Also eine Funktion, in der die Adresse einer anderen Funktion gespeichert wird. Diese Adresse kann man variieren und so über den gleichen Funktionsaufruf verschiedene Funktionen aufrufen.
Das schwierigste beim Programmieren ist, sinnvolle Variablen- und Funktionsnamen zu finden :lol:
BlackJack

@mzh: Selbst wenn die Funktionen bekannt sind: Stell Dir mal vor es sind 20 Funktionen die mit den selben 10 Argumenten aufgerufen werden sollen. Da will man ja nicht wirklich 20 verschiedene Funktionsaufrufe mit den selben Argumenten hinschreiben.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Praxisbeispiel: Ein GUI-Toolkit bietet die Möglichkeit, bei Klick auf einen Button eine Funktion aufzurufen. Zur Schreib-Zeit des Toolkits ist aber natürlich noch nicht festgelegt, welche Funktion das sein wird; die wird ja vom Benutzer/Programmierer angegeben.

Code sagt mehr als Worte:

Code: Alles auswählen

def on_button_clicked(btn):
    print '%r was clicked' % btn

btn = Button()
btn.connect('clicked', on_button_clicked)
`btn` speichert jetzt intern (z.B. in einer Liste) eine Referenz auf die Callback-Funktion, und wenn jemand auf den Knopf draufdrückt, ruft das Toolkit alle registrierten Callback-Funktionen auf.

Das Ganze nennt sich Event Driven Programming :-)
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

Vielen Dank für die Hinweise. Ich glaube, ich muss da einfach mehr Erfahrung haben, weil da mir fehlt da echt noch der Praxisbezug.
[url=http://www.proandkon.com]proandkon.com[/url]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Häufig findet man auch durchaus so etwas:

Code: Alles auswählen

def foo():
    print "bin in foo()"

def bar():
    print "bin in bar()"

# Binden von Funktion an Schlüsselwörter
dispatch = {
    "a": foo,
    "b": bar,
    "c": foo
}
# Benutzereingabe
choice = raw_input("Bitte Option wählen")
# je nach Buchstabe verzweigt das Programm woanders hin
dispatch[choice]()
Ein weiteres einfaches Beispiel wären Spiele wie TicTacToe und Konsorten. Die reine Spiellogik braucht ja nur wissen, welchen Zug ein Spieler wählt. Wie es zu der Auswahl kommt, wäre dabei ja egal. Somit kann man neben einem menschlichen Spieler auch eine KI basteln. Baut man die Logik unabhängig von der konkreten Auswahlfunktion, so kann man verschiedene Scenarien zur Laufzeit durchfühen, also Mensch vs. Mensch, KI vs. Mensch, Ki vs. KI.

Ich habe so etwas ähnliches mal vor Urzeiten benutzt, als ich das Ziegenproblem implementiert habe. (Der Code ist nicht PEP8 konform und teilweise krude) Interessant hierbei sind die beiden Parameter in der Funktion riddle(), die die eigentliche Logik implementiert. Hier übergibt man die Funktionen, die die Auswahl realisieren und die dann von der Spiellogik aufgerufen werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@mzh: Wenn Du Dich gerade mit GUI-Programmierung beschäftigst, dann bekommst Du doch ganz schnell den Praxisbezug -- bei den einfachsten GUI-Programme die irgendwie auf den Benutzer reagieren sollen, schreibst Du doch schon Callback-Funktionen.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

vielleicht muss man noch erwähnen, dass BJ gerade beim TR Beispiel eine gute Anwendung für Callback-Funktionen gezeigt hat:
http://www.python-forum.de/viewtopic.ph ... 52#p176552

Code: Alles auswählen

from operator import add, sub

operations = {
    1: add,
    2: sub
}
# Benutzer nach Menüauswahl fragen -> an "choice" binden
# Benutzer nach Operanden fragen -> an "op_a", "op_b" binden
# und dann der Aufruf:
operations[choice](op_a, op_b)
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

BlackJack hat geschrieben:@mzh: Wenn Du Dich gerade mit GUI-Programmierung beschäftigst, dann bekommst Du doch ganz schnell den Praxisbezug -- bei den einfachsten GUI-Programme die irgendwie auf den Benutzer reagieren sollen, schreibst Du doch schon Callback-Funktionen.
Das stimmt. Ich arbeite genau daran und möchte das einfach von Anfang an so gut wie möglich kapieren.
[url=http://www.proandkon.com]proandkon.com[/url]
Antworten