Seite 1 von 1
Globale Variable in Funktion erstellen
Verfasst: Freitag 10. April 2009, 11:54
von Spezmanu
Hi Leutz,
ich will über eine Funktion einen Button erstellen und diesem über eine andere Funktion seine Position im Grid-Raster zuweisen.
das problem ist wenn ich ihn wie gewohnt erstelle (Button1=Tkinter.Button...)
dann greift die zweite funktion nicht auf ihn zu.
Die Funktionen befinden sich im übrigen in der gleichen Quellcode-Datei.
lg Manuel
Verfasst: Freitag 10. April 2009, 12:10
von Birne94
globale Variablen sind eh nicht das beste o_O
Code: Alles auswählen
import Tkinter
button1 = None
def foo():
global button1
button1 = Tkinter.Button()
# ...
so müsste es imo gehen, wenn ich dich richtig verstehe^^
Verfasst: Freitag 10. April 2009, 12:22
von Dauerbaustelle
Sowas macht man normalerweise mit einer Klasse.
Verfasst: Freitag 10. April 2009, 12:27
von Spezmanu
ich hatte mir eig gedacht, dass ich das außerhalb der funktion nicht deklarieren muss, da der Variablenname durch exec nicht immer gleich ist.
trotzdem danke
Verfasst: Freitag 10. April 2009, 12:32
von nemomuk
Zeig doch mal deinen Code - global ist eigentlich fast nie nötig.
Verfasst: Freitag 10. April 2009, 12:36
von EyDu
Du solltest wirklich vergessen, dass es "global" und "exec" gibt und es mit vernünftigen Mitteln (Klassen, Parameter, Dictionaries für "dynamisch erstellte Variablen") lösen. Was du vor hast, wird aus Designsicht in einer Katastrophe enden. Die Wartbarkeit deines Codes wird unmöglich und unerwartete Seiteneffekte werden die Runde machen.
Verfasst: Freitag 10. April 2009, 21:27
von Spezmanu
ich weiß, dass er unübersichtlich wird, deswegen kommentiere ich ja auch schon fleißig.
Aber mir persönlich fällt keine Alternativmöglichkeit ein.
Sinn des Programms ist es eine Veranstaltungsdatenbank zu verwalten, d.h. einfügen/ändern, drucken und löschen.
in der HTML-Version hatte ich die Auswahl mit ID und Eingabefeld gelöst, was ich nicht so toll fand.
Nun die Codes:
Code: Alles auswählen
def anlegen_pruef():
# Überprüft/Korrigiert die Eingaben [gekürzt]
# Danach werden die Button/Label der neuen Veranstaltung erstellt
neu_ID=tele_sql.alle(['autoincrement'])['autoincrement']-1 #ID der eingegebenen Veranstaltung wird aus der DB gelesen
neu_ver=tele_sql.suche(neu_ID,['ver_ID', 'ver_name','ver_ort','ver_datum','ver_time']) #Liest in DB den Satz bei neu_ID aus; nur Listenelemente werden zurückgegeben
global sqls
sqls=tele_sql.alle(['ver_ID','ver_name','ver_ort','ver_datum','ver_time','autoincrement']) # alle Datensätze werden aus der DB gelesen; Liste enthält Spaltennamen
# die folgenden exec's sind mein Problem
exec 'global ver'+str(neu_ID)
exec 'global ort'+str(neu_ID)
exec 'global datum'+str(neu_ID)
exec 'global pk'+str(neu_ID)
# ubersicht ist der Frame
exec 'ver'+str(neu_ID)+'=Tk.Radiobutton(ubersicht,indicatoron=0,text="'+neu_ver['ver_name'][0]+'",value='+str(neu_ID)+',variable=ver,command=ver_details).grid(column=1,sticky="we")' # Erstellt Buttons mit dem Veranstaltungsnamen. Ein Klick zeigt die Maske zum Drucken, Löschen und Ändern an
exec 'ort'+str(neu_ID)+'=Tk.Label(ubersicht,text="'+neu_ver['ver_ort'][0]+'").grid(column=2,sticky="we")' # Erstellt ein Label mit dem Veranstaltungsort
exec 'datum'+str(neu_ID)+'=Tk.Label(ubersicht,text="'+neu_ver['ver_datum'][0]+' '+neu_ver['ver_time'][0]+'").grid(column=3,sticky="we")' # Erstellt ein Label mit Datum und Uhrzeit der Veranstaltung
exec 'pk'+str(neu_ID)+'=Tk.Radiobutton(ubersicht,indicatoron=0,value='+str(neu_ID)+',variable=pk,command=pk_details).grid(column=4,sticky="we")' # Erstellt einen Button ohne Aufschrift; ein Klick zeigt die Preisklassen der Veranstaltung an; siehe 'def pk_details' weiter oben.
sort_ver() #folgender Code
Code: Alles auswählen
def sort_ver():
# Sortiert die Tabelle in 'ubersicht' nach den Veranstaltungsnamen
u1.config(font=("MS Sans Serif",8,"bold")) # 'u1' ('Veranstaltung') wird hervorgehoben, um die aktuelle Sortierung zu zeigen.
u2.config(font=("MS Sans Serif",8))
u3.config(font=("MS Sans Serif",8))
zusortieren=[]
for i in range(len(sqls['ver_name'])): # Der Datensatz mit den Veranstaltungsnamen wird durchlaufen
zusortieren+=[[sqls['ver_name'][i].lower(),sqls['ver_ID'][i]]] # Die Namen werden mit den zugehörigen IDs in 'zusortieren' kopiert; Groß-/Kleinschreibung wird irrelevant.
zusortieren.sort() # Die Liste 'zusortieren' wird nach den Veranstaltungsnamen sortiert (Algorithmus von Python implementiert)
for i in range(len(zusortieren)): # Sortierte Liste 'zusortieren' wird durchlaufen
# Die Tabelleninhalte werden nach der Reihenfolge in 'zusortieren' geordnet; Ausschlaggebend ist hierbei der Objektname:
exec 'ver'+str(zusortieren[i][1])+'.grid(row='+str(i+3)+')'
exec 'ort'+str(zusortieren[i][1])+'.grid(row='+str(i+3)+')'
exec 'datum'+str(zusortieren[i][1])+'.grid(row='+str(i+3)+')'
exec 'pk'+str(zusortieren[i][1])+'.grid(row='+str(i+3)+')'
Wer eine einfachere/verständlichere Form findet, kann sie gerne posten.
Ich hoffe ich hab an alle Variablen gedacht
Verfasst: Freitag 10. April 2009, 22:00
von EyDu
Das kommt so sehr nah an den grausamsten Code ran, den ich jemals gesehen habe. Und das ist wirklich ernst gemeint!
Die globals kannst du dir sparen: alles was du in einer Funktion brauchst übergibst du als Parameter, alles was rausgehen soll als Rückgabewert. Wenn du feststellst, dass du unglaublich viele Parameter und Rückgabewerte haben solltest, dann ist das meist ein Hinweis auf ein schlechtes Design. Entweder macht die Funktion dann zu viel auf einmal und du solltest sie zerlegen oder du benötigst eine neue Struktur: Klassen, anderes Design, ...
Um die ganzen "exec"-Aufrufe zu vermeiden machst du daraus ein Dictionary mit deinen erzeugten Variablennamen als Schlüssel und den Widgets als Werte. Oder noch besser: die IDs als Schlüssel und alle dazugehörigen Widgets als ein Wert (über ein Tupel oder wieder ein Dictionary). Wenn du das korrigiert hast, dann kann man dir sicher weiterhelfen.
Noch ein paar weitere Tipps:
Du kannst direkt über Werte einer Liste iterieren, das "len" kannst du dir sparen. Wenn du dennoch den Index brauchst, da suche in der Dokumentation nach "enumerate".
Auch wenn du es nach den Verbesserungen nicht mehr brauchen wirst: Strings setzt man selten mit "+" zusammen, es gibt eine extra String-Formatting-Syntax. Steht auch in der Doku.
Benutze Konstanten!
Kommentare besser in eine Extrazeile und nicht hinten dran. Wie auch für den Code gilt: nicht mehr als 80 Zeichen pro Zeile.
Blick auf PEP8 würde nicht schaden.
Verfasst: Samstag 11. April 2009, 01:37
von audax
omg. Hast du mal das Python-Tutorial durchgearbeitet?
Verfasst: Samstag 11. April 2009, 14:37
von lunar
audax hat geschrieben:omg. Hast du mal das Python-Tutorial durchgearbeitet?
Nein, warum sollte er auch, dem Code nach zu urteilen hat er doch langjährige Erfahrung in PHP *scnr*
Edit: "wieso" durch "warum" ersetzt

Verfasst: Sonntag 12. April 2009, 11:50
von nuss
@lunar
lunar
BeitragVerfasst am: Sa Apr 11, 2009 15:37 Titel:
audax hat folgendes geschrieben:
omg. Hast du mal das Python-Tutorial durchgearbeitet?
Nein, wieso sollte er auch, dem Code nach zu urteilen hat er doch langjährige Erfahrung in PHP *scnr*
*loooooooooooool* *seehr herzhaft lach* *am kugel boden* ich mein *am boden kugeln*
nur das wieso hättest du durch warum ersetzen sollen

Verfasst: Sonntag 12. April 2009, 12:59
von lunar
nuss hat geschrieben:nur das wieso hättest du durch warum ersetzen sollen

Mmmh, gibt es da irgendeinen bedeutenden semantischen Unterschied zwischen "wieso" und "warum", der mir entgangen ist?
Verfasst: Sonntag 12. April 2009, 13:13
von nuss
Ist Semantisch gesehen einwandfrei, klingt nur irgendwie
nicht so ganz richtig in meinen Ohren. Mag auch nur so'n kleiner Spleen sein,
oder ostwestfälischer Dialekt wie meine Freundin sagen würde.
edit:
musste übrigens auch erste noch 2 mal drüber lesen, bis ich zum Schuluss gekommen bin, dasses korrect ist

Verfasst: Sonntag 12. April 2009, 21:39
von birkenfeld
Komisch, nach meinem (quasi-)bayrischen Sprachgefühl hätte ich jetzt "wieso" für die preußischere [1] Variante gehalten.
[1] für bayrische Werte von "preußisch" natürlich...
Verfasst: Montag 13. April 2009, 08:46
von EyDu
nuss hat geschrieben:musste übrigens auch erste noch 2 mal drüber lesen, bis ich zum Schuluss gekommen bin, dasses korrect ist

Das erinnert mich an "Contactlinsen"-Schilder ^^
Neben "wieso" und "warum" hätten wir auch noch "weswegen" und "weshalb".
Verfasst: Montag 13. April 2009, 10:13
von Spezmanu
Mein letztes PY-Tutorial war vor vier Jahren und nannte sich Unterricht, bei dem unser Lehrer mit uns zusammen Python lernte.
Das mit PHP stimmt mehr oder weniger, das hatte ich auf meine Profektpartnerin abgewälzt, während ich mich mit der Druckersprache abgequält hatte.
------------
Genitiv ins mehr, denn es ist Dativ.