如何编写在 python 而不是 shell 中执行的 ipython 别名?

How to write an ipython alias which executes in python instead of shell?

我们可以用%alias魔法函数在ipython中定义一个alias,像这样:

>>> d
NameError: name 'd' is not defined
>>> %alias d date
>>> d
Fri May 15 00:12:20 AEST 2015

当您将 d 键入 ipython 时,这会转义到 shell 命令 date

但我想定义一个别名来在当前解释器范围内执行一些 python 代码,而不是 shell 命令。那可能吗?我们如何制作这种别名?

我经常使用交互式解释器,这可以让我省去很多我发现自己经常重复的命令,还可以防止一些常见的拼写错误。

执行此操作的正常方法是简单地编写一个 python 函数,其中包含一个 def。但是如果你想给一个statement起别名,而不是一个函数调用,那么它实际上有点棘手。

您可以通过编写自定义 magic 函数来实现。这是一个示例,它在 REPL 中有效地将 import 语句别名为 get

from IPython.core.magic_arguments import argument, magic_arguments

@magic_arguments()
@argument('module')
def magic_import(self, arg):
    code = 'import {}'.format(arg)
    print('--> {}'.format(code))
    self.shell.run_code(code)

ip = get_ipython()
ip.define_magic('get', magic_import)

现在可以执行别名为 import 语句的 get 语句。

演示:

In [1]: get json
--> import json

In [2]: json.loads
Out[2]: <function json.loads>

In [3]: get potato
--> import potato
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<string> in <module>()

ImportError: No module named potato

In [4]: 

当然,这可以扩展到任意 python 代码,并且 optional arguments are supported aswell.

不知道什么时候IPython提供了宏。现在你可以简单地这样做:

ipy = get_ipython()
ipy.define_macro('d', 'date')

您可以将此代码放入位于 ~/.ipython/profile_default/startup/ 的任何文件中,然后当您启动时此宏将自动可用 IPython。

但是,宏不接受参数。所以请在选择定义宏之前牢记这一点。