Seite 2 von 2
Verfasst: Samstag 2. Dezember 2006, 21:22
von sape
rolgal_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.
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 next

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...
Verfasst: Samstag 2. Dezember 2006, 21:28
von sape
Code: Alles auswählen
x = {"foo": "bar", "blub": "spam"}
print x
y = x.iteritems()
print y.next()
print y.next()
print y.next()
output:
Code: Alles auswählen
{'foo': 'bar', 'blub': 'spam'}
('foo', 'bar')
('blub', 'spam')
Traceback (most recent call last):
[...]
print y.next()
StopIteration
Es wird also bis StopIteration iteriert. Und nichts anderes machen list(), etc auch

Verfasst: Samstag 2. Dezember 2006, 21:30
von sape
EDIT: Ach so: das dran eine liste rauskommt ist normal, weil list() alle Elemente die es vom Generator kriegt dort reinfügt.
Verfasst: Samstag 2. Dezember 2006, 21:42
von rolgal_reloaded
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.
Danke, war etwas wirr das Ganze, aber ich glaube ich habs:
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
Verfasst: Samstag 2. Dezember 2006, 22:55
von birkenfeld
Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:
ist das gleiche wie
Verfasst: Samstag 2. Dezember 2006, 23:00
von sape
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``.
Durch die Listcomprehension wird list() aufgerufen, welches alle Elemente, die es vom Generator bekommt......,richtig?
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.
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.
Verfasst: Samstag 2. Dezember 2006, 23:07
von birkenfeld
XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
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.
Verfasst: Samstag 2. Dezember 2006, 23:53
von rolgal_reloaded
birkenfeld hat geschrieben:Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:
ist das gleiche wie
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. - ?
LG
rolgal_reloaded
Verfasst: Samstag 2. Dezember 2006, 23:55
von sape
birkenfeld hat geschrieben:XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
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.
Ah, ok, danke dir

Damit solte das Mysterium geklärt sein.
BTW: @all: dis.dis(...) ist Super

^^
lg
Verfasst: Samstag 2. Dezember 2006, 23:56
von rolgal_reloaded
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
Verfasst: Samstag 2. Dezember 2006, 23:59
von sape
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
Verfasst: Sonntag 3. Dezember 2006, 00:10
von rolgal_reloaded
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

Verfasst: Sonntag 3. Dezember 2006, 00:12
von birkenfeld
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.
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.
Verfasst: Sonntag 3. Dezember 2006, 00:22
von Leonidas
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.
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.
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()
Nun stellt die Klasse SimplifiedVCS einfach nur ein vereinfachtes Interface zu seiner Elternklasse dar und nutzt dessen Funktionen. Ok, das Beispiel ist zugegebenermaßen ziemlich konstruiert

Verfasst: Sonntag 3. Dezember 2006, 12:19
von BlackJack
rolgal_reloaded hat geschrieben: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>
Ich meine: wenn ich mit iterkeys() in deinem Code der Klasse MyDict dasselbe bekomme wie mit meiner Listcomprehension
, dann müsste ich doch in der oben gezeigten interaktiven Sitzung auch mehr rausbekommen als einen schönen Gruß übern Interpreter
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.
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']
Verfasst: Sonntag 3. Dezember 2006, 14:01
von rolgal_reloaded
@Leonidas, @Blackjack,
wunderbar eure Antworten, leuchtet mir alles ein.
LG
rolgal_reloaded