Dictionary- Konstruktor
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
@Leonidas,
ah ja, ich bin wieder mit dabei, wobei mich die Designfrage weniger quält, also die, die ich wohl gleich stellen werde
LG
rolgal_reloaded
ah ja, ich bin wieder mit dabei, wobei mich die Designfrage weniger quält, also die, die ich wohl gleich stellen werde
LG
rolgal_reloaded
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
...hm, ich glaube die Variante von birkenfeld ohne Konstruktor, da ich ihn sowieso nicht brauche ist für den Unterricht besser.
Die Geschichte mit *args und **kwargs könnte einiges an Verwirrung sorgen.
rolgal_reloaded
Die Geschichte mit *args und **kwargs könnte einiges an Verwirrung sorgen.
rolgal_reloaded
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Wie schon gesagt, ist das natürlich eine schöne Sache mit iterkeys() usw.BlackJack hat geschrieben:So übergibst Du einfach alles an den Konstruktor von `dict()` was Dein Konstruktor so bekommt:
Ausserdem hab' ich die unnötigen List-Comps rausgeworfen.Code: Alles auswählen
class MyDict(dict): def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) def items(self): return sorted(self.iteritems()) def values(self): return sorted(self.itervalues()) def keys(self): return sorted(self.iterkeys())
Das mit den Schlüsselwort-Argumenten war übrigens eine blöde Idee von den Python-Machern -- man kann `dict()` nicht beerben und der neuen Klasse Schlüsselwortargumente hinzufügen ohne das sich die Semantik ändert. Bei dem sortierten Dict wäre es ja zum Beispiel schön im Konstruktor eine Schlüsselfunktion zum sortieren anzugeben.
Wenn man damit im Interpreter rumspielt bekommt man aber folgendes:
Code: Alles auswählen
>>> d = {"Italien":"Rom","Spanien":"Madrid","Belgien":"Brüssel","Frankreich":"Paris"}
>>> d.items()
[('Spanien', 'Madrid'), ('Italien', 'Rom'), ('Frankreich', 'Paris'), ('Belgien', 'Br\xfcssel')]
>>> d.keys()
['Spanien', 'Italien', 'Frankreich', 'Belgien']
>>> d.iterkeys()
<dictionary-keyiterator object at 0x01553D60>
Code: Alles auswählen
def keys(self):
return sorted([key for key in self])
Das check ich grad nicht ganz.
LG
rolgal_reloaded
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Meinst du "<dictionary-keyiterator object at 0x01553D60>"?
Das ist ein sogenannter Iterator, also ein Objekt, welches nacheinander die Keys eines dict bereitstellt, wenn man auf ihm next() aufruft.
Was sollte iterkeys() sonst zurückgeben? Es soll ja gerade keine Liste sein.
Das ist ein sogenannter Iterator, also ein Objekt, welches nacheinander die Keys eines dict bereitstellt, wenn man auf ihm next() aufruft.
Was sollte iterkeys() sonst zurückgeben? Es soll ja gerade keine Liste sein.
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
@birkenfeld
Eigentlich schon klar, aber in BlackJacks Beispiel bekomme ich dasselbe heraus, wie in meinem Beispiel mit einer Listcomprehension. Also eben sehr wohl Listen!
Deshalb bin ich verwirrt.
Eigentlich schon klar, aber in BlackJacks Beispiel bekomme ich dasselbe heraus, wie in meinem Beispiel mit einer Listcomprehension. Also eben sehr wohl Listen!
Deshalb bin ich verwirrt.
Nein, wenn du "list(x.iterkeys)", oder sonnt ein Objekt mit ner Generator Methode, mit list, tumple, etc benutzt, dann iterieren die selber darüber, also ruft nextrolgal_reloaded hat geschrieben:@birkenfeld
Eigentlich schon klar, aber in BlackJacks Beispiel bekomme ich dasselbe heraus, wie in meinem Beispiel mit einer Listcomprehension. Also eben sehr wohl Listen!
Deshalb bin ich verwirrt.
Beispiel
tuple(x.iterkeys()), list(x.iterkeys()), for i in x.iterkeys():
lg
EDIT: Wenn du "selber" iterieren willst geht das so:
y = x.iteritems()
y.next()
y.next()
etc...
Code: Alles auswählen
x = {"foo": "bar", "blub": "spam"}
print x
y = x.iteritems()
print y.next()
print y.next()
print y.next()
Code: Alles auswählen
{'foo': 'bar', 'blub': 'spam'}
('foo', 'bar')
('blub', 'spam')
Traceback (most recent call last):
[...]
print y.next()
StopIteration
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Danke, war etwas wirr das Ganze, aber ich glaube ich habs:XtraNine hat geschrieben:EDIT: Ach so: das dran eine liste rauskommt ist normal, weil list() alle Elemente die es vom Generator kriegt dort reinfügt.
Durch die Listcomprehension wird list() aufgerufen, welches alle Elemente, die es vom Generator bekommt......,richtig?
edit: Da habe ich vor lauter Lösungen wieder mal alles durcheinander geworfen, naja, eigenltich egal, der Thread ist so oder so gelöst.
LG
rolgal_reloaded
Zuletzt geändert von rolgal_reloaded am Sonntag 3. Dezember 2006, 14:48, insgesamt 1-mal geändert.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:
ist das gleiche wie
Code: Alles auswählen
l = [f(x) for x in y]
Code: Alles auswählen
l = []
for x in y:
l.append(f(x))
Naja wie das genau intern abläuft weiß ich nicht. Die Antwort überlasse ich den Profis hier. Eins steht auf jeden Fall fest, das ``[]``, ``()``, ``list()``, ``tuple()`` genauso in der Lage sind zu iterieren wie z.B. ``for``.
Aber wie gesagt, wie das ganz genau intern abläuft weiß ich nicht.
EDIT: Hier noch ein Thread wo Birkenfeld den unterschied zwischen {} und dict{} erklärt hat, was sich auch auf list() übertragen lässt: http://www.python-forum.de/topic-8119.h ... hlight=24h
EDIT2: Wider zu spät.
Ne nicht ganz: Für ``[]`` wird der Opcode ``BUILD_LIST`` aufgerufen. ``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?). Die sorgen nun dafür das bei einem Generator die ``.next()``-Methode aufgerufen wird und gibt bei jeder Iteration ein Element wider, bis ein ``StopIteration`` ausgelöst wird und das iterieren beendet wird.Durch die Listcomprehension wird list() aufgerufen, welches alle Elemente, die es vom Generator bekommt......,richtig?
Aber wie gesagt, wie das ganz genau intern abläuft weiß ich nicht.
EDIT: Hier noch ein Thread wo Birkenfeld den unterschied zwischen {} und dict{} erklärt hat, was sich auch auf list() übertragen lässt: http://www.python-forum.de/topic-8119.h ... hlight=24h
EDIT2: Wider zu spät.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Nicht ganz: da brauchts keinen Opcode mehr, weil der Typ "list" ja direkt in C implementiert ist und daher nur die entsprechende C-API-Funktion aufruft.XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Ist mir klar, dann wird halt was äquvivalentes wie list() aufgerufen. Es wird in jedem Fall eine Liste erzeugt, die bewirt, dass sich iterkeys() usw. sich so verhält wie oben beschrieben. - ?birkenfeld hat geschrieben:Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:
ist das gleiche wieCode: Alles auswählen
l = [f(x) for x in y]
Code: Alles auswählen
l = [] for x in y: l.append(f(x))
LG
rolgal_reloaded
Ah, ok, danke dir Damit solte das Mysterium geklärt sein.birkenfeld hat geschrieben:Nicht ganz: da brauchts keinen Opcode mehr, weil der Typ "list" ja direkt in C implementiert ist und daher nur die entsprechende C-API-Funktion aufruft.XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
BTW: @all: dis.dis(...) ist Super ^^
lg
Zuletzt geändert von sape am Samstag 2. Dezember 2006, 23:56, insgesamt 1-mal geändert.
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.
Das ist mir jetzt nur mal so durch den Kopf gegangen.
Ich habe aber nicht wirklich die Erfahrung und das KnowHow das wirklich zu beurteilen.
Vielleicht gibts noch andere Meinungen dazu.
LG
rolgal_reloaded
Das ist mir jetzt nur mal so durch den Kopf gegangen.
Ich habe aber nicht wirklich die Erfahrung und das KnowHow das wirklich zu beurteilen.
Vielleicht gibts noch andere Meinungen dazu.
LG
rolgal_reloaded
-
- User
- Beiträge: 312
- Registriert: Dienstag 24. Oktober 2006, 19:31
XtraNine hat geschrieben:Puh, das weiß ich nicht. Das kann ich ncoh nicht beurteilen weil mir die entsprechende Erfahrung fehlt.
Aber mal ganz im vertrauen: BlackJacks Code haben zu 99% Hand und Fuss Der weis __GANZ__ genau was er da Treibt
lg
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Wieso? In vielen Fällen ruft man in der überschriebenen Methode die entsprechende Methode der Elternklasse auf. In diesem Fall ist es aber sinnvoller, da effizienter, eine andere Methode der Elternklasse zu verwenden.rolgal_reloaded hat geschrieben:Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Warum sollte sowas seltsam sein? Eine Kindklasse erweitert die Elternklasse ja und kann dabei doch durchaus auf Dinge zurückgreifen die die Elternklasse schon bietet - warum das Rad noch einmal erfinden? Dass eine von dict abgeleitete Klasse die Funktion iteritems() bietet, davon ist auszugehen - es wäre seltsam Dinge in der Kindklasse zu löschen.rolgal_reloaded hat geschrieben:Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.
Stellt euch vor, die Elternklasse macht etwas sehr flexibel und für den Benutzer dieser Klasse unpraktisch. Gehen wir mal vom Beispiel einer Klasse zur Versionsverwaltung aus:
Code: Alles auswählen
class HighlyFlexibleVCS(object):
def update(self):
# Code um den Checkout zu aktualisieren
pass
def pull(self):
# Code um den aktuellen Code aus einem entfernten Repository zu holen
pass
def commit(self):
# Code um etwas einzuchecken
pass
def push(self):
# Code um den aktualisierten Code an ein entferntes Repository zu schicken
pass
class SimplifiedVCS(HighlyFlexibleVCS):
def download(self):
self.pull()
self.push()
def upload(self):
self.commit()
self.push()
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Die Liste oder der Iterator werden als Argument an `sorted()` übergeben. Wichtig ist was *diese* Funktion zurückgibt. Nämlich eine sortierte Liste mit den Elementen des "iterable", das als Argument übergeben wurde.rolgal_reloaded hat geschrieben:Wenn man damit im Interpreter rumspielt bekommt man aber folgendes:
Ich meine: wenn ich mit iterkeys() in deinem Code der Klasse MyDict dasselbe bekomme wie mit meiner ListcomprehensionCode: Alles auswählen
>>> d = {"Italien":"Rom","Spanien":"Madrid","Belgien":"Brüssel","Frankreich":"Paris"} >>> d.items() [('Spanien', 'Madrid'), ('Italien', 'Rom'), ('Frankreich', 'Paris'), ('Belgien', 'Br\xfcssel')] >>> d.keys() ['Spanien', 'Italien', 'Frankreich', 'Belgien'] >>> d.iterkeys() <dictionary-keyiterator object at 0x01553D60>
, dann müsste ich doch in der oben gezeigten interaktiven Sitzung auch mehr rausbekommen als einen schönen Gruß übern InterpreterCode: Alles auswählen
def keys(self): return sorted([key for key in self])
Code: Alles auswählen
In [1]: d = {"Italien":"Rom","Spanien":"Madrid","Belgien":"Brüssel","Frankreich":"Paris"}
In [2]: d.iterkeys()
Out[2]: <dictionary-keyiterator object at 0xb7951300>
In [3]: sorted(d.iterkeys())
Out[3]: ['Belgien', 'Frankreich', 'Italien', 'Spanien']