Seite 1 von 1

Datenströme

Verfasst: Mittwoch 28. April 2010, 10:55
von Goswin
Hallo Forum, ich wünsche euch einen schönen guten Morgen!

Ich arbeite mit zwei Modulen: Das erste erzeugt zufallsverteilt eine große Menge Strings und schreibt sie in eine Datei; das zweite liest die Strings aus der dieser Datei und erzeugt damit allerlei erfreuliche Grafiken für den Benutzer. Alles funktioniert bestens mit zwei Ausnahmen, die in Wirklichkeit eine und diesselbe sind:
  • (1) Das zweite Modul muss warten, bis die gesamte Datei geschrieben wurde, was mich manchmal ungeduldig macht.
    (2) Ich kann das Gesamtprogramm nicht unbeschränkt lange laufen lassen, da die Datei natürlich endlich lang ist.
Im Grunde genommen habe ich einen Datenstrom, welcher erzeugt und danach ausgewertet wird. Anderseits muss ich die beiden Module aber unbedingt getrennt halten, da es für beide Module verschiedene Alternativen gibt und sie beliebig kombinierbar sein sollen.
Eine mögliche Lösung scheint mir Nebenläufigkeit mit zwei Threads zu sein (habe noch nie so etwas programmiert), oder vielleicht eine indirekte Nebenläufigkeit wo ich irgendwo Generatorfunktionen einbaue (habe ich auch noch nie gemacht). Das Ganze scheint mir ziemlich kompliziert zu sein; übersehe ich vielleicht eine einfache Lösung? In Java soll es Dinge wie 'outputstream' und 'inputstream' geben, aber ich wüßte nicht, welches das pythonische Gegenstück dazu ist...

Vielen dank für eure Hinweise und sonstigen Bemerkungen!

Verfasst: Mittwoch 28. April 2010, 11:07
von Pekh
Die Lösung sind tatsächlich Threads. Beschäftige dich dort vor allem mit dem Produzent- Verbraucher-Problem und wie du konkurrierende Zugriffe vermeiden kannst.

Verfasst: Mittwoch 28. April 2010, 11:07
von BlackJack
@Goswin: Muss das denn unbedingt über eine Datei gehen? Das Modul bzw. das Objekt was die Zeichenketten erzeugt ist bereits als Generator oder Iterator implementiert?

Verfasst: Mittwoch 28. April 2010, 11:40
von ms4py
BlackJack hat geschrieben:@Goswin: Muss das denn unbedingt über eine Datei gehen? Das Modul bzw. das Objekt was die Zeichenketten erzeugt ist bereits als Generator oder Iterator implementiert?
Genau, einfach so in dieser Art:

Code: Alles auswählen

def string_generator():
    while True:
        yield generate_random_string()

def create_graphics():
    for string in string_generator():
        process(string)

Verfasst: Mittwoch 28. April 2010, 12:09
von Goswin
BlackJack hat geschrieben:Muss das denn unbedingt über eine Datei gehen?
Voraussichtlich nicht; ich kann das Modul leicht umschreiben (was ich aus anderen Gründen sowieso tun muss). Falls Generatoren so einfach wie im Beitrag von ms4py zu handhaben sind (was ich demnächst ausprobieren werde), dann wäre das wahrscheinlich die Lösung, die ich suche. Ich habe halt keine Erfahrung mit Gerneratoren und wusste nicht, ob diese auch Modul-übergreifend funktionieren oder nicht.

So nebenbei: ist ein ein sogenannter Generator eigentlich
  • a) eine Art von Iterable?
    b) eine Art von Iterator?
    c) beides?, oder
    d) keines von beiden?

Verfasst: Mittwoch 28. April 2010, 12:36
von Rebecca
http://docs.python.org/tutorial/classes.html#generators hat geschrieben: Generators are a simple and powerful tool for creating iterators. [...] Anything that can be done with generators can also be done with class based iterators as described in the previous section. What makes generators so compact is that the __iter__() and next() methods are created automatically.
EDIT: Also eigentlich beides. Iterables haben eine __iter__-Methode, welche einen Iterator zurueckgibt (welcher widerum eine next-Methode hat). Meist gibt die __iter__-Methode das Objekt selbst (self) zurueck, welches dann eben __iter__ und next implementiert, also sowohl Iterable als auch Iterator ist.

Verfasst: Donnerstag 29. April 2010, 08:54
von Goswin
PEP_255 Specification hat geschrieben:When a generator function is called, [...] a generator-iterator object is returned.
Ist das nicht schlichtweg falsch? Wenn eine Generator-Funktion (also eine Funktion mit einem yield-Befehl) aufgerufen wird, dann wird doch keineswegs der entsprechende Iterator selber ausgegeben, sondern der Rückgabewert der __next__-Methode des Iterators. Oder etwa nicht?

Verfasst: Donnerstag 29. April 2010, 08:59
von ms4py
Goswin hat geschrieben:
PEP_255 Specification hat geschrieben:When a generator function is called, [...] a generator-iterator object is returned.
Ist das nicht schlichtweg falsch? Wenn eine Generator-Funktion (also eine Funktion mit einem yield-Befehl) aufgerufen wird, dann wird doch keineswegs der entsprechende Iterator selber ausgegeben, sondern der Rückgabewert der __next__-Methode des Iterators. Oder etwa nicht?
Nope, das ist völlig richtig (und hättest du auch selbst ausprobieren können).

Code: Alles auswählen

>>> def generator():
...     for i in xrange(3):
...             yield i
...
>>> type(generator())
<type 'generator'>
>>> iterator = generator()
>>> iterator.next()
0

Verfasst: Donnerstag 29. April 2010, 09:53
von Goswin
@ms4py: Du hast recht. Ich hatte es vor 1 Jahr ausprobiert, aber offenbar falsch in Erinnerung.


@Rebecca: Vielen Dank für deinen Hinweis, dass Generatoren

Code: Alles auswählen

def __iter__(self): return self
haben. Auf so etwas wäre ich nie gekommen.