Seite 1 von 1

Grundlagen: Klassen als Iteratoren

Verfasst: Dienstag 13. Januar 2009, 17:37
von ChrisGTJ
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

Verfasst: Dienstag 13. Januar 2009, 18:11
von Trundle
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()
...

Verfasst: Dienstag 13. Januar 2009, 18:16
von rayo
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

Verfasst: Dienstag 13. Januar 2009, 18:41
von numerix
<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ß>

Verfasst: Mittwoch 14. Januar 2009, 10:10
von ChrisGTJ
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

Verfasst: Mittwoch 14. Januar 2009, 15:03
von Masaru
ChrisGTJ hat geschrieben:Warum Klugscheiß?
Weil mans kann und einfach riesen Spass macht :twisted:

Verfasst: Donnerstag 15. Januar 2009, 10:00
von ChrisGTJ
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