Seite 1 von 1
Frage zu ´command=´ im Zusammenhang mit for-Schleifen
Verfasst: Mittwoch 10. Juni 2009, 16:04
von Pascal
Hallo!
Ich bin dabei ein Programm zu schreiben, dass Sounds abspielt, sobald man auf diesen Button klickt.
Dafür hab ich eine Prozedur
mit der ich entsprechende Sounds abspielen lassen kann.
Danach habe ich Buttons erstellt etc.
Code: Alles auswählen
def play_test01(e):
play_sound('test01')
But=Button(root, text = 'test01')
But.pack()
Widget.bind(But, '<Button-1>', play_test01)
Das funktioniert wunderbar, jedoch will ich nicht für für jeden Sound eine eigene Prozedur!
Das ganze will ich jetzt über eine for-Schleife lösen:
Code: Alles auswählen
titel=['test01', 'test02']
for tit in titel:
Button(root, command= play_sound(tit), text=tit).pack()
Dabei passiert folgendes:
Der Sound wird abgespielt, danach erscheint der Button.
Wird der Button geklickt, so passiert nichts.
Eine andere Variante:
Code: Alles auswählen
for tit in titel:
Button(root, command=lambda: play_sound(tit), text=tit).pack()
Dabei passiert folgendes:
Die Button erscheinen. Klickt man einen diesen Button an, so wird 'test02' abgespielt, obwohl die Beschriftung stimmt!
Kann mir jemand sagen, was ich verändern muss?
Verfasst: Mittwoch 10. Juni 2009, 16:51
von EyDu
Ja, die Idee mit "lambda" war schon nicht schlecht, dass macht aber beim Erzeugen von Funktionen Probleme. Ich empfehle daher die Funktion "partial" aus dem "functools"-Modul:
Code: Alles auswählen
import functools
...
for tit in titel:
Button(root, command=functools.partial(play_sound, tit), text=tit).pack()
Edit: habe noch mal kurz über deinen Code geschaut, da sind mir noch ein paar Dinge aufgefallen:
- wähle besser aussagekräftige Bezeichner; "But" ist ein wirklich nichtssagender Name für einen Button; außerdem sollte du dich für eine Sprache entscheiden: Deutsch oder Englisch.
- "Variablennamen" solltest du klein schreiben: Statt "But" also "but".
- um die Leerzeichen bei Zuweisungen solltest du Leerzeichen setzen, bei Parametern allerdings nicht
- die Letzten beiden Punkte, und noch etwas mehr, kannst du auch in PEP8 nachlesen.
Verfasst: Mittwoch 10. Juni 2009, 19:18
von Pascal
Danke für deine Antwort
Aber ist das richtig so:
Code: Alles auswählen
>>> import functools
Traceback (most recent call last):
File "<pyshell#1>", line 1, in ?
import functools
ImportError: No module named functools
Ist das nicht bei den Standardmodulen dabei?
zum Edit:
"But" kann ich ja weglassen, das war eh nur als temporärer Name gedacht.
Das mit Deutsch und Englisch... jaaaa...
ich werd mich bemühen
Immerhin bin ich schon vom *-import weggekommen

Verfasst: Mittwoch 10. Juni 2009, 19:32
von BlackJack
@Pascal: Wie alt ist denn Dein Python? Das Modul gibt es seit 2.5.
Verfasst: Mittwoch 10. Juni 2009, 19:32
von derdon
http://docs.python.org/library/functools
Dort ist der erste Satz:
New in version 2.5.
Verfasst: Mittwoch 10. Juni 2009, 20:11
von Pascal
Ich hab 2.4
Na Toll
Ich kann aber nicht finden, wo man das noch runterladen kann...
Verfasst: Mittwoch 10. Juni 2009, 20:22
von numerix
Pascal hat geschrieben:Ich hab 2.4
Na Toll
Ich kann aber nicht finden, wo man das noch runterladen kann...
Was für ein "das"? Du meinst doch nicht etwa Python >2.4?

Verfasst: Mittwoch 10. Juni 2009, 20:27
von Pascal
Ich hab die Version 2.4
mal schauen was sich machen lässt...
Verfasst: Mittwoch 10. Juni 2009, 21:15
von Pascal
Ok 2.6 runtergeladen.. morgen geht´s weiter
Verfasst: Donnerstag 11. Juni 2009, 12:31
von Pascal
numerix hat geschrieben:
Was für ein "das"? Du meinst doch nicht etwa Python >2.4?

ich meinte das modul
Alternative zu partial
Verfasst: Montag 7. September 2009, 17:58
von Pascal
Hallo Leute,
gerade frage ich mich, wie ohne "partial" auskommt, wenn man eine Funktion mit Parametern aufrufen will. Dies gilt speziell für Tkinter, wenn 'event' bereits ein Parameter ist.
Grund ist, dass wir in der Schule 2.4 haben, also ohne functools
Was kann ich machen?
Verfasst: Montag 7. September 2009, 18:15
von jbs
Zur Not kannst du dir ja die Funktion aus der Dokumentation herauskopieren.
Verfasst: Montag 7. September 2009, 18:49
von Pascal
jbs hat geschrieben:Zur Not kannst du dir ja die Funktion aus der Dokumentation herauskopieren.
schön wärs:
Aus dem functools-Modul:
Code: Alles auswählen
from _functools import partial, reduce
...
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
...
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
schade...

Verfasst: Montag 7. September 2009, 19:01
von audax
Code: Alles auswählen
def play_sound(title):
print "playing ", title
for title in ["foo", "bar"]:
def _play(e):
play_sound(title)
Button(root, command=_play, text=title).pack()
Oder auch die "lambda e,title=title: play_sound(title)" Variante. Dadurch wird das Argument gebunden und die Variable nicht überschrieben.
Verfasst: Montag 7. September 2009, 19:17
von cofi
Pascal hat geschrieben:schön wärs:
http://docs.python.org/library/functools.html hat geschrieben:functools.partial(func[, *args][, **keywords])
Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords. Roughly equivalent to:
Code: Alles auswählen
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
Verfasst: Montag 7. September 2009, 19:27
von Pascal
cofi hat geschrieben:
Code: Alles auswählen
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
ich weiß nicht, was ich mit dem Rückgabewert anfangen soll...

Verfasst: Montag 7. September 2009, 19:43
von BlackJack
@Pascal: An einen Namen binden!? Als Argument übergeben, zum Beispiel als `command`-Argument bei `Tkinter`-Buttons!? Darum ging's doch in diesem Thema, oder?