Verständnisproblem bei Dictionaries

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
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo Liste,

nachdem hier mehrfach auf "Learn Python The Hard Way" hingewiesen wurde, habe ich mich näher mit diese Lektüre beschäftigt und habe ein Verständnisproblem mit folgendem Script:

Code: Alles auswählen

cities = {'CA': 'San Francisco', 'MI': 'Detroit', 'FL': 'Jacksonville'}
cities['NY'] = 'New York'
cities['OR'] = 'Portland'

def find_city(themap, state):
    if state in themap:
        return themap[state]
    else:
        return "Not found!"
    
cities['_find'] = find_city

while True:
    print "State? (Enter to quit)",
    state = raw_input("> ")
    if not state: break
    city_found = cities['_find'](cities, state)
    print city_found
So wie ich das verstehe, wird mit "cities['_find'] = find_city" die Funktion find_city unter dem Key '_find' in das dict eingefügt und ist gleichzeitig eine Art Aliasname für "find_city". :K
Mal davon abgesehen, dass ich das vermutlich falsch verstanden habe, stellt sich für mich auch die Frage, wo jetzt die Vorteile zu dem folgenden Sprict bestehen:

Code: Alles auswählen

cities = {'CA': 'San Francisco', 'MI': 'Detroit', 'FL': 'Jacksonville'}
cities['NY'] = 'New York'
cities['OR'] = 'Portland'

def find_city(state):
    try:
        return cities[state]
    except:
        return "Not found!"
    
while True:
    print "State? (Enter to quit)",
    state = raw_input("> ")
    if not state: break
    print find_city(state)
Kann mir mal jemand auf die Sprünge helfen.

Klaus
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

KlausS hat geschrieben:So wie ich das verstehe, wird mit "cities['_find'] = find_city" die Funktion find_city unter dem Key '_find' in das dict eingefügt und ist gleichzeitig eine Art Aliasname für "find_city". :K
Ja, kann man so lagen.
Mal davon abgesehen, dass ich das vermutlich falsch verstanden habe, stellt sich für mich auch die Frage, wo jetzt die Vorteile zu dem folgenden Sprict bestehen:
Es gibt keine. So ohne Kontext ist die Verwendung unsinnig. Sieht eher so aus als würde da versuch ein Dictionary als Namensraum oder Klasse zu missbrauchen. Daten und Funktionen in einem Dictionary zu mischen ist auf jeden Fall eine schlechte Idee.

Deine Version ist besser, mit der Einschränkung, dass du auch eine spezifische Ausnahme abfangen solltest, statt alle möglichen. In diesem Fall wäre das wohl ein KeyError. Außerdem würde ich keine globalen Variablen verwenden und stattdessen das Städte-Dictionary der Funktion übergeben.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nein, das hast du schon richtig verstanden `cities['_find']` ist ein alias fuer `find_city`. Ein Vorteil ergibt sich dadurch nicht direkt, aber es demonstriert, dass man Funktionen in Dictionaries stecken kann und wie man sie daraus nutzt.

An dem Code lassen sich auch ein paar Sachen beanstanden: Das `break` sollte in eine eigene Zeile, damit man es nicht so leicht uebersieht und blanke `except` sollte man nicht nutzen, v.a. nicht wenn es wie hier genau eine erwartete und behandelte Exception gibt.
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo Darii,

danke für die schnelle Antwort. Dann bleibe ich mal bei meiner Variante (mit KeyError), denn die verstehe ich auch :P

Klaus
BlackJack

@KlausS: Einfach weiterlesen -- schon am Anfang der nächsten Übung wird das ausgiebig erklärt.

@Darii: Das da Werte und Funktionen im gleichen Dictionary stecken ist Absicht. Das ist der Übergang zu syntaktischem Zucker dafür -- Klassen:
Learning Python The Hard Way -- Exercise 42: Getting Classy hat geschrieben:While it’s fun to put functions inside of dictionaries, you’d think there’d be something in Python that does this for you. There is and it’s the class keyword. Using class is how you create an even more awesome “dict with functions” than the one you made in the last exercise.
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

@BlackJack
Ich habe auch die beiden folgenden Kapitel gelesen. Aber so richtig weiter hat mich das bezüglich der Funktion in einem dict noch nicht gebracht :K

Ich mach jetzt erstmal Pause und lasse das sacken.

Klaus
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Na, Wörterbücher liefern eben Werte zurück, wenn der Schlüssel abgefragt wird. Ein Wert kann in Python jede Art von Objekt sein. Es ist also grundsätzlich möglich, etwas wie "abc" oder 123 an den Schlüsselnamen zu binden oder eben auch ein Objekt, das eine Funktion ist. Man könnte für den späteren Aufruf in der Endlosschleife auch einen Zwischenschritt einsetzen, falls dir das nicht ganz klar war:

Code: Alles auswählen

find_city_func = cities['_find']
city_found = find_city_func(cities, state)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

BlackJack hat geschrieben:@Darii: Das da Werte und Funktionen im gleichen Dictionary stecken ist Absicht. Das ist der Übergang zu syntaktischem Zucker dafür -- Klassen:
Klassen sind mehr als syntaktischem Zucker für Dictionaries. Vor allem stecken bei Klassen die Funktionen normalerweise in der Klasse und nicht in der Instanz. Das Beispiel aus dem Buch ist jedenfalls so dämlich, dass man es lieber nicht gebracht hätte.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Darii hat geschrieben:Klassen sind mehr als syntaktischem Zucker für Dictionaries. Vor allem stecken bei Klassen die Funktionen normalerweise in der Klasse und nicht in der Instanz. Das Beispiel aus dem Buch ist jedenfalls so dämlich, dass man es lieber nicht gebracht hätte.
Natürlich sind sie dass aber an diesem Punkt ist das völlig egal.

Das Beispiel ist (prinzipiell) genial als Einführung in die OOP, da es mit vertrauten Mitteln sämtliche Grundlagen zeigen kann. Ich denke dass das Beispiel eines Bank Accounts, wie es SICP macht, konkret besser wäre da es zeigt wie man Status kapseln kann statt diesen auf Modulebene zu haben aber dies ist ja erstmal ein Detail.

Sicherlich stellen Klassen, in Python, eine elegantere Lösung für das Problem dar aber wenn man jemandem einen Hammer in die Hand gibt bevor man erklärt hat dass es Nägel gibt trägt man sicherlich nicht zum Verständnis bei.
lunar

@DasIch: Wenn Klassen nur syntaktischer Zucker für Wörterbücher sind, wie genau finden sich dann Vererbung und Deskriptoren in Wörterbüchern? Und sag jetzt bitte nicht, dass man Vererbung ja theoretisch auch mit Wörterbüchern implementieren könnte ... das ist dann nämlich eine Implementierung, und somit wesentlich mehr als bloßer syntaktischer Zucker.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Natürlich hast du Recht, Metaklassen finden sich da ja auch nicht. Alles wesentliche Dinge die man alle auf einmal möglichst gleichzeitig und sofort bis ins kleinste Detail lernen und verstehen muss wenn man mit OOP anfängt.

Wo kämen wir den da hin wenn man sowas Schritt für Schritt erklärt, gleich fordert noch jemand dass sowas leicht verständlich werden soll und ruft die Revolution aus.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

DasIch hat geschrieben:Das Beispiel ist (prinzipiell) genial als Einführung in die OOP, da es mit vertrauten Mitteln sämtliche Grundlagen zeigen kann.
Wieso ist das völlig überflüssige Ablegen einer Funktion in einem Dict eine gute Einführung in OOP? Welche Grundlagen werden da denn da gezeigt?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das einzige, was gezeigt wird, sind Namensräume. Allerdings in einer Art und Weise, die in Python unüblich ist. Für Namensräume sind, wenn man gute Gründe (genug Namen) hat, Module geschaffen worden. Klassen und Wörterbücher hingegen sind erstmal nicht als Container für Funktionen gedacht. Man sollte sich sowas gar nicht erst angewöhnen. Ein gutes und einfaches Beispiel, um an die Thematik "Namensraum" heranzuführen, wäre es also IMHO gewesen, wenn das Buch an dieser Stelle Module eingeführt hätte.
BlackJack

Da wird das Zusammenfassen von Daten und Funktionen in einer Datenstruktur gezeigt -- eben was man mit Klassen auch macht. Mehrwert ist zum Beispiel Polymorphie.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

snafu hat geschrieben:Ein gutes und einfaches Beispiel, um an die Thematik "Namensraum" heranzuführen, wäre es also IMHO gewesen, wenn das Buch an dieser Stelle Module eingeführt hätte.
Sicherlich und danach darf man den Leuten hier erklären wieso global eine schlechte Idee ist.
Antworten