Seite 1 von 1

Fragen eines anfängers (Programmaufbau/Datei laden

Verfasst: Montag 27. Juli 2009, 20:32
von banthrass
Hallo zusammen,

ich bin ganz neu im Forum und hoffe hier auf guten Support :). Ich habe vor kurzem (einige Stunden) erst mit Python angefangen. Meine Literatur beschränkt sich bisher auf "A Byte of Python".

Naja....wagemutig wie ich bin, will ich direkt ein kleines Verwaltungsprogramm für meine Arbeit schreiben. In diesem Programm soll es die Möglichkeit geben Etwas mit bestimmten Eigenschaften anzulegen, zu bearbeiten, zu löschen und halt...zu verwalten.

Nun zu meiner ersten Frage:
Wie sollte ich ein solches Programm aufbauen? Also gibt es bestimmte Regeln nach denen ich sowas Aufbauen sollte?

Ich gebe mal ein Beispiel:
Ich dachte mir eine Datei für diverse Funktionen anzulegen und für jeden Bereich wie "Anlegen" , "Löschen" usw. ebenfalls eine eigene Datei anzulegen. Ist sowas sinnvoll oder eher nicht ? Gibt es bessere....sinnsollere Methonden für sowas?

Ob es so nun sinnvoll ist oder nicht, trotz alle dem würde ich gerne wissen wie man Dateien laden kann.....ähnlich dem "include" Befehl bei PHP vielleicht. Damit ich z.B. eine Datei namens "funktionen.py" irgendwo "include" um auf dessen Inhalt (die Funktionen eben) zu greifen kann.

Na das wars erst mal. Ich hoffe mir kann da mal jemand ein paar Infos geben.

Danke :)

//Ich

Verfasst: Montag 27. Juli 2009, 20:45
von Birne94
Ob es so nun sinnvoll ist oder nicht, trotz alle dem würde ich gerne wissen wie man Dateien laden kann.....ähnlich dem "include" Befehl bei PHP vielleicht. Damit ich z.B. eine Datei namens "funktionen.py" irgendwo "include" um auf dessen Inhalt (die Funktionen eben) zu greifen kann.

Code: Alles auswählen

import funktionen
funktionen.blah()
oder

Code: Alles auswählen

from funktionen import blah
blah()

Verfasst: Montag 27. Juli 2009, 21:29
von cofi
Ordne deinen Code semantisch und nicht syntaktisch, d.h. packe zusammen was zusammen gehoert und nicht nach Art getrennt.
Im kontreten Fall: ``admin.py`` fuer deine administrativen Teile (was du hier ``funktionen.py`` nennst), ``backend.py`` fuer die Persistenz und ``frontend.py`` fuer die GUI/CLI.

Im Tutorial solltest du dir vielleicht auch den Abschnitt ueber Module durchlesen.

Verfasst: Dienstag 28. Juli 2009, 18:37
von banthrass
Hallo :)

Danke für die Antworten. Die haben mir weiter geholfen :).

Verfasst: Mittwoch 29. Juli 2009, 06:48
von AntagonisT
Ich habe eine ganz ähnliche Frage zum Design von Programmen.

Hier erstmal ein kleines Testbeispiel zur Veranschaulichung:
GUI: http://paste.pocoo.org/show/131392/
APP: http://paste.pocoo.org/show/131393/

das Tool ist zweigeteilt in gui und app und man kann damit in ein Entry-widget Text eingeben und speichern, bzw. abgespeicherte Texte in das Entry-widget laden. Dabei importieren sich beide Dateien gegenseitig (sozusagen kreuzweise), da sie ja voneinander "wissen" müssen.

Ist das guter Stil? Macht man das so? Wenn nicht, wie macht man das sonst?

Verfasst: Mittwoch 29. Juli 2009, 07:20
von BlackJack
@AntagonisT: Kreuzweise importieren ist kein guter Stil und führt früher oder später auch zu handfesten Problemen. Schreib es so, dass die beiden nicht voneinander wissen müssen. In der Anwendungslogik sollte keine GUI bekannt sein müssen. Damit wäre die bei dem Beispiel dann allerdings so minimal, dass eine Auslagerung in ein eigenes Modul übertrieben ist.

Insgesamt ist das alles zu "global" und fest verdrahtet. Code auf Modulebene sollte sich auf Definitionen von Konstanten, Funktionen und Klassen beschränken. Und nicht veränderbare Objekte mit so nichtssagenden Namen wie `x` dort ablegen.

Verfasst: Mittwoch 29. Juli 2009, 08:00
von AntagonisT
BlackJack hat geschrieben:Schreib es so, dass die beiden nicht voneinander wissen müssen. In der Anwendungslogik sollte keine GUI bekannt sein müssen.
Es geht hier auch nur um das Prinzip. Wie kann ich denn Daten an die GUI übergeben, wenn mein APP die gar nicht kennt? :K
Ich könnte die als Parameter in die APP-Funktionen übergeben, aber wenn ich jetzt 40 entry-widgets habe, die alle gespeichert/eingelesen werden sollen... ist das nicht auch umständlich?

BlackJack hat geschrieben:Insgesamt ist das alles zu "global" und fest verdrahtet. Code auf Modulebene sollte sich auf Definitionen von Konstanten, Funktionen und Klassen beschränken.
Da waren sie wieder, meine 3 Probleme: Klassen, Klassen und Klassen.. :lol:
Ich versuche seit ein paar Tagen, durchzusteigen, wozu die gut sein sollen; hier im Forum, Tutorials, Bücher. Ich. check. es. einfach. nicht!

Ich packe mein gui also in eine Klasse und dann ist gut? Oder wie ist das zu verstehen?

Verfasst: Mittwoch 29. Juli 2009, 08:44
von Leonidas
AntagonisT hat geschrieben:Wie kann ich denn Daten an die GUI übergeben, wenn mein APP die gar nicht kennt? :K
Du übergibst keine Daten an die GUI, die GUI holt sich die Daten. Dadurch weiß die GUI von dem Backend aber das Backend muss nichts von der GUI wissen.

Verfasst: Mittwoch 29. Juli 2009, 09:36
von snafu
Poste bitte demnächst lauffähigen Code. Nachdem ich alle Vorkommnisse von `tkinter` durch `Tkinter` und `filedialog` durch `FileDialog` ersetzt habe, erhalte ich trotzdem eine Fehlermeldung:

Code: Alles auswählen

~/bin/py/test$ python gui.py
Traceback (most recent call last):
  File "gui.py", line 2, in <module>
    import app
  File "/home/sebastian/bin/py/test/app.py", line 2, in <module>
    import gui    
  File "/home/sebastian/bin/py/test/gui.py", line 13, in <module>
    b1 ["command"] = app.file_open
AttributeError: 'module' object has no attribute 'file_open'
Ich kann sie mir nicht erklären. Vielleicht liegt es an den zirkulären Importen.

Verfasst: Mittwoch 29. Juli 2009, 09:40
von cofi
Im Uebrigen ist das alles GUI, sollte also in einem Modul sein. Besser noch in einer Klasse die das GUI modelliert.

Verfasst: Mittwoch 29. Juli 2009, 10:00
von AntagonisT
danke an alle Antworter.

@snafu: Das ist mit Python 3.1 lauffähig! und ja, das Problem könnte an den zirkulären Importen liegen. Kommt drauf an, welches der beiden Scripte Du startest...:wink:



neuer Versuch, diesmal ohne kreuzweise Importe, dafür ein unschönes Definitions-Hilfskonstrukt in meiner GUI:

GUI: http://paste.pocoo.org/show/131410/
APP: http://paste.pocoo.org/show/131411/

das mit "lambda" habe ich in der Zwischenzeit auch herausgefunden.

Verfasst: Mittwoch 29. Juli 2009, 10:03
von AntagonisT
cofi hat geschrieben:Im Uebrigen ist das alles GUI, sollte also in einem Modul sein. Besser noch in einer Klasse die das GUI modelliert.
AAAHHH, wo hört denn die GUI dann auf? Für mich war das bisher die reine Darstellung der Fenster, widgets, etc... und die übergeben alle "commands", Eingabewerte, etc... an ein anderes Modul.

Verfasst: Mittwoch 29. Juli 2009, 10:06
von snafu
AntagonisT hat geschrieben:Das ist mit Python 3.1 lauffähig!
Das sollte man im Moment noch dazu schreiben. IMHO ist Python 2.6 momentan die meistverwendetste Version (ich möchte mich jetzt mal nicht zu "Standard" hinreißen lassen).
AntagonisT hat geschrieben:und ja, das Problem könnte an den zirkulären Importen liegen. Kommt drauf an, welches der beiden Scripte Du startest...:wink:
Ich habe `gui.py` gestartet, weil dort der Mainloop aufgerufen wird.

EDIT: `app.py` läuft. Ich werde mir jetzt mal deinen neuen Code angucken...

Verfasst: Mittwoch 29. Juli 2009, 10:07
von Leonidas
AntagonisT hat geschrieben:AAAHHH, wo hört denn die GUI dann auf? Für mich war das bisher die reine Darstellung der Fenster, widgets, etc... und die übergeben alle "commands", Eingabewerte, etc... an ein anderes Modul.
Die GUI hört dort auf, wo die algorithmische Berechnung beginnt, die das Problem löst. Bei dir gibt es so einen Teil gar nicht, also ist alles GUI.

Richtwert: es sollte möglich sein, eine andere Oberfläche, zum Beispiel Textoberfläche oder Weboberfläche mit deinen nicht-GUI-Code zu verknüpfen. Dann hast du ordentliche Separation. Wenn aber überall in deinem Code Fenster aufgemacht werden oder eingaben entgegengenommen werden, dann ist eben alles (G)UI.

Verfasst: Mittwoch 29. Juli 2009, 10:15
von snafu
Um mal ein Beispiel zu nennen: Mit viel Wohlwollen könnte man eine Funktion `save_as_textfile()` schreiben, die Dateinamen und Inhalt annimmt (ohne den `filedialog`). Diese wäre dann unabhängig von der GUI verwendbar. Bei der jetzigen Größe deines Programms würde ich aber - wie schon von mehreren Vorrednern gesagt - alles in ein einziges Modul packen.

EDIT:

Code: Alles auswählen

def save_as_textfile(filename, content):
    if not filename.endswith('.txt'):
        filename += '.txt'
    with open(filename, 'w') as textfile:
        textfile.write(str(content))

Verfasst: Mittwoch 29. Juli 2009, 11:18
von AntagonisT
snafu hat geschrieben:
AntagonisT hat geschrieben:Das ist mit Python 3.1 lauffähig!
Das sollte man im Moment noch dazu schreiben. IMHO ist Python 2.6 momentan die meistverwendetste Version (ich möchte mich jetzt mal nicht zu "Standard" hinreißen lassen).
sorry, wird in Zukunft gemacht!

Verfasst: Mittwoch 29. Juli 2009, 11:41
von AntagonisT
Leonidas hat geschrieben:Richtwert: es sollte möglich sein, eine andere Oberfläche, zum Beispiel Textoberfläche oder Weboberfläche mit deinen nicht-GUI-Code zu verknüpfen. Dann hast du ordentliche Separation. Wenn aber überall in deinem Code Fenster aufgemacht werden oder eingaben entgegengenommen werden, dann ist eben alles (G)UI.
Danke, das hört sich gut an!

snafu hat geschrieben:Um mal ein Beispiel zu nennen: Mit viel Wohlwollen könnte man eine Funktion `save_as_textfile()` schreiben, die Dateinamen und Inhalt annimmt (ohne den `filedialog`). Diese wäre dann unabhängig von der GUI verwendbar.
stimmt, den filedialog müsste ich natürlich noch rüber tun. Man sieht so viele Offensichtlichkeiten noch nicht, wenn man sich mit den elementarsten Dingen rumschlagen muss...

snafu hat geschrieben:Bei der jetzigen Größe deines Programms würde ich aber - wie schon von mehreren Vorrednern gesagt - alles in ein einziges Modul packen.

EDIT:

Code: Alles auswählen

def save_as_textfile(filename, content):
    if not filename.endswith('.txt'):
        filename += '.txt'
    with open(filename, 'w') as textfile:
        textfile.write(str(content))
wie gesagt, das sollte nur ein kleines Testbeispiel sein, um erstmal ein mögliches Prinzip auszuprobieren. Das eigentliche GUI wird in etwa so ausschauen:

Bild