Ausgabe pro Zelle für IPython-Notizbücher

8

Ich möchte das nicht als ein Problem ansprechen, weil es wie eine völlig unangemessene Feature-Anforderung für ein ziemlich erstaunliches Tool erscheint. Aber wenn Leser mit der Architektur vertraut sind, würde ich gerne wissen, ob eine mögliche Erweiterung machbar ist.

Ich habe kürzlich ein Notizbuch mit einem einfachen Thread geschrieben, um zu sehen, was passieren würde, wenn ich es ausführen würde. Der Notebook-Code (tl; dr startet eine Reihe paralleler Threads, die in einer Schlafschleife gedruckt werden) ist unter Ссылка verfügbar.

Wenn Sie SHIFT-RETURN einige Male drücken, während der Code ausgeführt wird, können Sie beobachten, dass jede Ausgabe des Kernels im Ausgabebereich der aktuellen Zelle erscheint, nicht in der Zelle, in der der Code ausgeführt wurde.

Ich frage mich, ob es möglich wäre, wenn Threads für eine Zelle aktiv wären, eine "Refresh" -Schaltfläche anzuzeigen, die es ermöglicht, den Ausgabebereich asynchron zu aktualisieren. Im Idealfall würde die Schaltfläche zum Aktualisieren verschwinden, wenn nach dem Beenden aller Threads (nach einem letzten Update) geklickt wurde.

Dies hängt jedoch davon ab, ob es möglich ist, die Druckausgabe für jeden Thread zu identifizieren und abzufangen und sie in einen Puffer für die Ausgabe der spezifischen Zelle zu leiten. Also, zwei Fragen.

  1. Habe ich recht, wenn ich daran glaube, dass die gedruckte Anweisung von Python 2 dies bedeutet? Diese Erweiterung kann nicht mit einem Standard-Interpreter implementiert werden?

  2. Sind die Aussichten für Python 3 besser, da es möglich ist, einen anderen zu schleichen? layer in den print () - Stack innerhalb des IPython - Kernels und besonders für diejenigen, die keinem Python - Link folgen, um hierher zu gelangen,

  3. [Niemand erwartet die spanische Inquisition] Allgemeiner können Sie auf (sprachunabhängige) Beispiele verweisen von mehreren Streams auf einer Seite geliefert werden? Gibt es etablierte Best Practices? um das DOM zu konstruieren und zu modifizieren?

holdenweb 18.01.2013, 07:05
quelle

1 Antwort

13

UPDATE:

  

Habe ich Recht, wenn ich glaube, dass die Hard-Verdrahtung der Python 2-Anweisung print bedeutet, dass diese Erweiterung nicht mit einem Standard-Interpreter implementiert werden kann?

Nein, die wichtigen Teile der Print-Anweisung sind nicht fest verdrahtet. print schreibt einfach in sys.stdout, das ein beliebiges Objekt mit den Methoden write und flush sein kann. IPython ersetzt dieses Objekt bereits vollständig, um von vornherein stdout auf das Notebook zu bekommen (siehe unten).

  

Sind die Aussichten für Python 3 besser, da es möglich ist, eine andere Ebene in den print () - Stack innerhalb des IPython-Kernels zu schleusen, und besonders für diejenigen, die keinem Python-Link folgen, um hierher zu gelangen,

Nein - überschreiben sys.stdout ist alles was Sie brauchen, nicht selbst drucken (siehe oben, unten und anderswo). Python 3 hat hier keine Vorteile.

  

[Niemand erwartet die spanische Inquisition] Können Sie allgemeiner auf (sprachunabhängige) Beispiele verweisen, wie mehrere Ströme auf eine Seite geliefert werden?

Sicher - das IPython-Notebook selbst. Es verwendet Nachrichten-IDs und Metadaten, um den Ursprung von stdout-Nachrichten zu ermitteln. und wiederum, wo diese Nachrichten enden sollten. Unten, in meiner ursprünglichen Antwort auf eine Frage, die scheinbar niemand fragte, zeige ich ein Beispiel für das gleichzeitige Zeichnen von Ausgaben aus mehreren Zellen, deren Threads gleichzeitig ausgeführt werden.

Um das von Ihnen gewünschte Aktualisierungsverhalten zu erhalten, müssten Sie wahrscheinlich zwei Dinge tun:

  1. Ersetzen Sie sys.stdout durch Ihr eigenes Objekt, das das IPython-Anzeigeprotokoll zum Senden von Nachrichten mit Ihren eigenen Thread-identifizierenden Metadaten verwendet (z. B. threading.current_thread().ident ). Dies sollte in einem Kontextmanager erfolgen (wie unten), so dass es nur die Druckanweisungen betrifft, die Sie wirklich wollen.
  2. schreibe ein IPython js-Plugin für die Handhabung deines neuen Formats von stdout-Nachrichten, damit sie nicht sofort gezeichnet werden, sondern in Arrays gespeichert werden, die darauf warten, gezeichnet zu werden.

Ursprüngliche Antwort (falsche, aber verwandte Frage):

Es beruht auf einigen Fehlern und privaten APIs, aber dies ist mit dem aktuellen IPython durchaus möglich (es kann nicht ewig sein).

Hier ist ein Beispiel-Notizbuch: Ссылка

Um dies zu tun, müssen Sie verstehen, wie IPython von vornherein das stdout auf dem Notebook bekommt. Dies geschieht, indem sys.stdout durch ein OutStream -Objekt ersetzt wird. Dies puffert Daten und sendet sie dann über zeromq, wenn sys.stdout.flush aufgerufen wird. und es endet schließlich im Browser.

Nun, wie man die Ausgabe an eine bestimmte Zelle sendet.

Das IPython Nachrichtenprotokoll verwendet einen "Eltern" -Kopf, um zu identifizieren, welche Anfrage welche Antwort erzeugt hat. Jedes Mal, wenn Sie IPython bitten, Code auszuführen, wird die übergeordnete Kopfzeile verschiedener Objekte (sys.stdout eingeschlossen) so dass ihre Nebenwirkungsnachrichten mit der Nachricht verknüpft sind, die sie verursacht hat. Wenn Sie Code in einem Thread ausführen, bedeutet dies, dass der aktuelle parent_header nur der letzte execute_request ist. anstatt der ursprünglichen, die einen bestimmten Thread gestartet hat.

Vor diesem Hintergrund ist hier ein Kontextmanager, der stdout den übergeordneten Header temporär auf einen bestimmten Wert setzt:

%Vor%

Und hier ist ein Thread, der den Elternteil aufnimmt, wenn der Thread beginnt, und wendet dieses Elternteil jedes Mal an, wenn es eine Druckanweisung abgibt, so verhält es sich, als wäre es noch in der ursprünglichen Zelle:

%Vor%

Und schließlich, ein Notizbuch, das alles zusammenhält, mit Zeitstempeln, die den tatsächlichen gleichzeitigen Druck auf mehrere Zellen anzeigen:

Ссылка

    
minrk 18.01.2013, 08:54
quelle