Grundlagen: Klassen als Iteratoren

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
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Hallo,

wenn ich eine Klasse haben möchte, die als Iterator verwendet werden kann (sagt man das so?), was brauche ich dann?

Ganz von Anfang an:

Code: Alles auswählen

def itera():
	yield "1"
	yield "2"
	
i = itera()
print i
print i.next()
print i.next()
print i.next()
ergibt als Ausgabe:

Code: Alles auswählen

<generator object at 0x00C070A8>
1
2
Traceback (most recent call last):
  File "Generator.py", line 22, in <module>
    print i.next()
StopIteration
Ich möchte jetzt eine Klasse haben, über die ich iterieren kann. Suche im Forum liefert mir u.a. folgendes:

http://www.python-forum.de/topic-16879. ... =generator

Aber das hilft mir nicht recht weiter. Wie benutze ich das Ding? Ich glaube verstanden zu haben, daß die Verwendung von "yield" implizit eine Methode next() liefert und daß die Verwendung von __iter__() die Klasse zu einem Generator macht. Offensichtlich ist das nicht so:

Code: Alles auswählen

class isIter( object):

	def __iter__( self):
		yield "1"
		yield "2"

i = isIter()
print i
print i.next()
print i.next()
print i.next()
ergibt:

Code: Alles auswählen

<__main__.isIter object at 0x00C03070>
Traceback (most recent call last):
  File "Generator.py", line 25, in <module>
    print i.next()
AttributeError: 'isIter' object has no attribute 'next'
Also bastele ich mal eine Methode next():

Code: Alles auswählen

class isIter( object):

	def next( self):
		yield "1"
		yield "2"

i = isIter()
print i
print i.next()
print i.next()
print i.next()
ergibt:

Code: Alles auswählen

<__main__.isIter object at 0x00C04070>
<bound method isIter.next of <__main__.isIter object at 0x00C04070>>
<generator object at 0x00BEBEE0>
<generator object at 0x00BEBEE0>
<generator object at 0x00BEBEE0>
So, hier ist mein Latein zu Ende. Irgendwas grundlegendes ist mir entgangen. In anderen Beispielen hier im Forum hat die Klasse dann noch die Methode

Code: Alles auswählen

def class ....
....
    def __iter__(self):
        return self
....
aber das führt auch nicht recht weiter. Ich würde mich über eine kurze Erklärung freuen.

Gruß und Danke,

Christoph
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Du musst noch sagen, dass du auch iterieren willst und nicht nur ein Exemplar der Klasse erstellen magst.

Code: Alles auswählen

i = iter(isIter())
print i
print i.next()
...
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

iter nicht vergessen, in einer for-Schleife passiert dies automatisch.
Beim 2. Beiscpiel kannst du natürlich viel komplizierteres machen, jetzt ist es ein sinnloses Beispiel.

Code: Alles auswählen

class test(object):
    def __iter__(self):
        yield 1
        yield 2
    

o = test()
i = iter(o)
print i
print i.next()
print i.next()

for x in o:
    print x

class test2(object):
    def __init__(self):
        self.items = [1,2,3,4]
        self.current_item = 0
    
    def next(self):
        tmp = self.items[self.current_item]
        self.current_item += 1
        if self.current_item == len(self.items):
            raise StopIteration()
        return tmp
    
    
    def __iter__(self):
        self.current_item = 0
        return self
    

o2 = test2()
i = iter(o2)
print i
print i.next()
print i.next()
print i.next()

for x in o2:
    print x
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

<klugscheiß>
In Python 3.0 gibt es die next()-Methode für Iteratoren nicht mehr.
Sie wurde umbenannt in __next__() und es wurde eine builtin-function next() ergänzt, die diese Methode aufruft. Statt

Code: Alles auswählen

i.next()
wird dann empfohlen

Code: Alles auswählen

next(i)
</klugscheiß>
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Hallo auch,

ich wußte es, es ist einfach... Danke Euch.

@numerix:

Warum Klugscheiß? Nicht jeder hat die Zeit, sich mit 3.0 zu befassen. Insofern finde ich solche Anmerkungen gut.

Gruß,

Christoph
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

ChrisGTJ hat geschrieben:Warum Klugscheiß?
Weil mans kann und einfach riesen Spass macht :twisted:
ChrisGTJ
User
Beiträge: 105
Registriert: Mittwoch 22. August 2007, 15:45

Masaru hat geschrieben:
ChrisGTJ hat geschrieben:Warum Klugscheiß?
Weil mans kann und einfach riesen Spass macht :twisted:
Äh - versteh ich was falsch? Ich empfinde es als gar nicht kluggeschissen, sondern als sehr hilfreich.

Gruß,

Christoph
Antworten