Seite 1 von 2
Re: Übungsprojekt meinAdressbuch
Verfasst: Freitag 14. Mai 2010, 18:36
von BlackJack
@ltownatze: Da könnte man mit Defaultargumenten arbeiten.
Code: Alles auswählen
def show_entry(ab, name=None):
if name is not None:
print name, ':', ab.get(name, 'not found, try `meinAdressbuch show | grep -i <NAME>`')
else:
pass # Irgendwas anderes machen.
Re: Übungsprojekt meinAdressbuch
Verfasst: Samstag 15. Mai 2010, 16:58
von ltownatze
Nicht ganz ohne Stolz präsentiere ich eine komplett überarbeitete Version von
meinAdressbuch
Wie immer freue ich mich auf kontruktive Kritik.
Edit: Ich spiele mit dem Gedanken Docstrings einzubauen.. haltet ihr das bei einem so kleinen Script/Modul/Programm[?] für Sinnvoll? Welchen Mehrwert hätte das für den Anwender/Programmierer?
Re: Übungsprojekt meinAdressbuch
Verfasst: Samstag 15. Mai 2010, 17:38
von BlackJack
@ltownatze: Ich sehe nicht so ganz den Mehrwert das in dieser Form in eine Klasse zu stecken. Ausser einmal ein Exemplar zu erzeugen, dass dann die Kommandozeilenargumente auswertet, kann man damit ja nicht viel machen.
Die Klasse vermischt zuviel. Die Benutzerinteraktion ist da mit drin, und man kann auch kein Adressbuch erzeugen, ohne das versucht wird etwas aus einer Datei zu laden.
Re: Übungsprojekt meinAdressbuch
Verfasst: Samstag 15. Mai 2010, 18:56
von ltownatze
BlackJack hat geschrieben:Ich sehe nicht so ganz den Mehrwert das in dieser Form in eine Klasse zu stecken.
Das schien mir die beste möglichkeit zu sein 'global' zu vermeiden ohne 'addressbook_filename' an jede Funktion übergeben zu müssen.
Meinen Recherchen und Experimenten zu Folge ist die Verwendung von 'self' nur innerhalb einer Klasse möglich.
Die möglichkeit über 'self' auf Referenzen aus dem Namensraum von 'MeinAdressbuch' zuzugreifen hat auserdem den positiven Nebeneffekt das ich problemlos auf 'parser.get_usage()' zugreifen kann.
Glaubst du ich sollte von der Klassen-Idee abstand nehmen?
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 09:58
von Hyperion
ltownatze hat geschrieben:
Glaubst du ich sollte von der Klassen-Idee abstand nehmen?
Ja! Zumindest von der, wie Du es jetzt machst.
Im Grunde wrappst Du nur Dictionary-Zugriffe und baust Speicher- und Lade-Mechanismen direkt in die Klasse ein. Du kannst doch genauso gut Funktionen schreiben, die ein Adressbuch-Dictionary ausgeben, sortieren usw. Das Laden und Speichern würde ich auch eher aus der Klasse rausziehen. Ist doch toll eine Funktion zu haben, die solch eine Klasse anlegen kann.
Prinzipiell würde ich erst einmal alles ohne Klassen versuchen. Solltest Du auf die Idee kommen, verschachtelte Datenstrukturen einzubauen, oder eine schönere Sortiermethode anzugehen, kann man später immer noch eine Art "Adresse"-Klasse bauen und die Objekte in einer Liste oder einem Dictionary halten.
Das Argument mit dem global habe ich nicht ganz verstanden. Den Dateinamen brauchst Du doch nur zum Laden und Speichern. Da müßtest Du ihn also an zwei Funktionen übergeben - imho nicht aufwendig

Aber dennoch braucht es da keine Klasse, um ein global zu vermeiden.
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 18:10
von ltownatze
Mal ne kleine Zwischenfrage:
Ich konnte in der Python-Dokumentation nichts in der Richtung finden und langsam glaube ich das es da auch nichts zu finden gibt bevor ich also weiter suche bis ich alt und grau bin hier meine Frage:
Mal angenommen ich habe 2 Funktionen: 'main()' und 'open_addressbook()':
Code: Alles auswählen
def main():
[...]
open_addressbook()
[...]
def open_addressbook():
addressbook_filename = 'einschönerdateiname'
und ich möchte die Variable 'addressbook_filename', nach dem Aufruf von open_addressbook(), in main() weiterverwenden.
Wie könnte ich hier vorgehen? Ist sowas überhaupt möglich?
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 18:41
von cofi
ltownatze hat geschrieben:Ist sowas überhaupt möglich?
Nein, gluecklicherweise geht das nicht. Du suchst Rueckgabewerte.
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 18:54
von ms4py
cofi hat geschrieben:ltownatze hat geschrieben:Ist sowas überhaupt möglich?
Nein, gluecklicherweise geht das nicht. Du suchst Rueckgabewerte.
Also mit Rückgabewerten lautet die Antwort eigentlich schon "Ja"
Code: Alles auswählen
def main():
[...]
addressbook_filename = open_addressbook()
[...]
def open_addressbook():
addressbook_filename = 'einschönerdateiname'
[...]
return addressbook_filename
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 18:56
von Hyperion
ms4py hat geschrieben:
Also mit Rückgabewerten lautet die Antwort eigentlich schon "Ja"
Bezogen auf "die Variable" im Ursprungspost aber dann eben doch "nein"

Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 19:59
von ltownatze
Mir fällt es noch etwas schwer mich präzise Auszudrücken.. aber ich wurde irgendwie Verstanden
Mit 'return' hatte ich auch schon rumgespielt, bin aber nicht auf diese Idee gekommen:
Außerdem hat mich die
Python-Doku hier etwas verwirrt.
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 20:02
von Hyperion
ltownatze hat geschrieben:
Außerdem hat mich die
Python-Doku hier etwas verwirrt.
Respekt für das Lesen der Doku, aber Du solltest erst einmal
hier gucken

Das sind wirklich absolute Baics.
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 20:43
von cofi
ltownatze hat geschrieben:Mit 'return' hatte ich auch schon rumgespielt, bin aber nicht auf diese Idee gekommen:
Um das klarzustellen: `addressbook_filename` ist NICHT dieselbe Variable, wie in der Funktion, sondern enthaelt den Rueckgabewert von `open_addressbook`, d.h. du kannst sie a) aendern, ohne den Wert in der Funktion zu aendern und b) aendert sich der Wert in der Funktion, dann aendert sich nicht der Wert dieser Variablen (es sei denn, du weisst ihr wieder den Rueckgabewert der Funktion zu).
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 20:53
von Hyperion
Was mir hier gerade noch auffällt: Wieso definiert man denn einen Dateinamen innerhalb einer Funktion? Irgend wie kein guter Stil...
Vielleicht noch mal ein simpleres Beispiel, um klar zu stellen, dass Namen jeweils in ihrem Scope eindeutig sind:
Code: Alles auswählen
In [1]: def foo():
...: a = "test"
...: return a
...:
In [2]: a = 3
In [3]: b = foo()
In [4]: print a, b
------> print(a, b)
(3, 'test')
Das 'a' auf Modulebene verweist auch nach dem Aufruf von foo() weiterhin auf 3. Dafür wird der Rückgabe
wert von foo() an den Namen 'b' gebunden.
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 21:11
von ltownatze
Danke für die ausführlichen und anschaulichen Erklärungen, ich habs jetzt endlich begriffen.
Wieso definiert man denn einen Dateinamen innerhalb einer Funktion? Irgend wie kein guter Stil...
Eigentlich ging es mir nicht um den Dateinamen sondern um ein Dictionary das aus einer Datei ausgelesen wird und dem/der Namen/Variable/Referenz (k.A. was jetzt der korrekte Begriff ist) 'addressbook' zugeordnet wird. In der Praxis sieht das so aus:
Code: Alles auswählen
def main():
[...]
addressbook = open_addressbook(addressbook_filename)
[...]
def open_addressbook(addressbook_filename):
try:
fp = open(addressbook_filename, 'r')
addressbook = json.load(fp)
fp.close()
except IOError:
addressbook = {}
return addressbook
Ist es in diesem Fall guter Stil?
Re: Übungsprojekt meinAdressbuch
Verfasst: Montag 17. Mai 2010, 21:26
von Hyperion
Datein würde ich immer mit with öffnen:
Code: Alles auswählen
with open(filename, "r") as infile:
addressbook = json.load(infile)
Damit sparst Du Dir das close() und bist auch sicher, dass die datei auch bei einer Exception geschlossen wird (wozu Du sonst ein finally benötigen würdest!)
Sieht doch so ganz gut aus
Einzig die Rückgabe eines leeren Dicts bei einem Fehler könnte man überdenken. So bekommt man ja keine Rückmeldung, ob das geklappt hat oder nicht!
Ich würde dann eher die Exception beim Auruf der Funktion abfangen und ggf. dort eine Meldung ausgeben. Mit einem leeren Dict kannst Du dann ja immer noch weiterarbeiten.