iPython宏操作

时间:2017-11-17 21:12:16

标签: python ipython

我是一名工程师,我在工作时使用python REPL作为高级计算器。我使用REPL的“先前输出”功能,通常是_。

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

类似的东西。

出于某种原因,我发现虽然输入下划线是一件苦差事。我使用了Haskell REPL,它使用“it”作为前一个输出变量,我发现它更容易输入。

我了解到iPython允许您定义执行某些代码的宏。所以我弹出一个iPython shell并定义了一个名为“it”的%宏,它模仿了“_”。

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

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

我可以这样称呼“它”:

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

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

但是,当我尝试使用it*4这样的“it”时,我会收到错误unsupported operand type(s) for *: 'Macro' and 'int'

我希望“it”是它返回的类型而不是Macro类型,因此我可以像使用“_”一样使用它。

2 个答案:

答案 0 :(得分:1)

您也可以更改分配_的代码,而不是转到宏路径。 here执行此操作并可以更改:

  

可以通过指定另一个来自定义这些值的显示   sys.displayhook的单参数函数。

所以我们可以简单地保存在__builtins__.it或任何你喜欢的名字:

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

这适用于普通的python shell,但不知何故ipython可以防止篡改sys.displayhook。 ipython中处理displayhook的代码在IPython.core.displayhook.DisplayHook中,所以我们可以修补:

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

这有点黑客。事情可能会破裂,但经过5秒的测试后,它似乎有效。

你可能不想在每次启动ipython时输入,但我们可以自动化。 sys.displayhook表示您可以简单地将文件放入~/.ipython/profile_default/startup/,然后每次都执行该文件。

答案 1 :(得分:0)

当我尝试时,我

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

宏包含' \ n'。所以独立it表现良好。但它无法在线使用。