2017-11-17 1 views
1

Ich bin ein Ingenieur und ich benutze eine Python REPL als ein fortgeschrittener Rechner während der Arbeit. Ich verwende die "vorherige Ausgabe" -Funktion der REPL, die oft _ ist.iPython Makros Operationen

>>>45*0.344 
15.48 
>>>_*2 
30.96 

So ähnlich.

Aus irgendeinem Grund finde ich es irgendwie mühsam, den Unterstrich einzugeben. Ich habe die Haskell REPL verwendet, die "it" als die vorherige Ausgabevariable verwendet, die ich leichter zu tippen finde.

Ich habe gelernt, dass iPython können Sie Makros definieren, die einige Code ausführen. Also habe ich eine iPython-Shell geöffnet und ein% -Makro namens "it" definiert, das das "_" nachahmt.

In [1]: _ 
Out[1]: '' 

In [2]: %macro it 1 
Macro `it` created. To execute, type its name (without quotes). 
=== Macro contents: === 
_ 

kann ich "es" etwa so:

In [1]: 4 
Out[1]: 4 

In [2]: it 
Out[2]: 4 

Allerdings, wenn ich versuche, etwas zu tun mit "es" wie it*4, erhalte ich die Fehler unsupported operand type(s) for *: 'Macro' and 'int'.

Ich möchte "es", um den Typ sein, der es anstelle des Typs Makro zurückgibt, damit ich es verwenden kann, genau wie ich "_" benutze.

Antwort

1

Anstelle der Makroroute können Sie auch den Code ändern, für den _ zugewiesen wird. sys.displayhook tut dies und kann geändert werden:

Die Anzeige dieser Werte können durch die Zuweisung einer anderen einargumentigen Funktion sys.displayhook angepasst werden.

So können wir einfach in __builtins__.it speichern oder was auch immer Namen, den Sie mögen:

import sys 
ipython_displayhook = sys.displayhook 
def mydisplayhook(value): 
    if value is not None: 
     __builtins__.it = value 
    return ipython_displayhook(value) 
sys.displayhook = mydisplayhook 

Diese in der normalen Python-Shell funktioniert, aber irgendwie verhindert ipython mit mit sys.displayhook Manipulation. Der Code in ipython, die die displayhook Griffe ist in IPython.core.displayhook.DisplayHook so können wir Affen-Patch, der:

import IPython.core.displayhook 
__call__ = IPython.core.displayhook.DisplayHook.__call__ 

def mycall(self, value): 
    if value is not None: 
     __builtins__.it = value 
    __call__(self, value) 

IPython.core.displayhook.DisplayHook.__call__ = mycall 

Dies ist ein bisschen hacky ist. Dinge können brechen, aber nach dem Testen für 5 Sekunden scheint es, dass es funktioniert.

Sie möchten wahrscheinlich nicht jedes Mal eingeben, wenn Sie ipython starten, aber wir können das automatisieren. This answer sagt, Sie können einfach eine Datei in ~/.ipython/profile_default/startup/ setzen, die dann jedes Mal ausgeführt wird.

+0

Ich mag diese Idee, aber, a) sollte displayhook nicht displayhandler sein, aber ich habe das geändert, und b) Ich bekomme einen NameError, dass "es" nicht definiert ist. Und ich bin bei Python nicht gut genug, um genau herauszufinden, was falsch ist. – chiiidog

+0

Irgendwie gemischt "Handler" und "Haken", sorry. Ich habe in der normalen Python-Shell getestet, und dort funktioniert diese Lösung tatsächlich. IPython verhindert zwar irgendwie das Ändern des Display-Hooks, aber durch Monkey-Anpassung können wir immer noch erreichen, was wir wollen. Siehe meine Bearbeitung. – syntonym

0

Wenn ich versuche, dass ich

In [329]: it.value 
Out[329]: '_\n' 

Das Makro enthält die '\ n' zu bekommen. So ein Stand alone it verhält sich in Ordnung. Aber es kann nicht in-line verwendet werden.