Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

We can define an alias in ipython with the %alias magic function, like this:

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

This escapes to the shell command date when you type d into ipython.

But I want to define an alias to execute some python code, in the current interpreter scope, rather than a shell command. Is that possible? How can we make this kind of alias?

I work in the interactive interpreter a lot, and this could save me a lot of commands I find myself repeating often, and also prevent some common typos.

like image 634
wim Avatar asked May 14 '15 14:05

wim


People also ask

Is IPython a shell?

IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history.

What is %% capture in Python?

IPython has a cell magic, %%capture , which captures the stdout/stderr of a cell. With this magic you can discard these streams or store them in a variable. from __future__ import print_function import sys. By default, %%capture discards these streams. This is a simple way to suppress unwanted output.

How do you use %% Timeit in Jupyter?

The “%timeit” is a line magic command in which the code consists of a single line or should be written in the same line for measuring the execution time. In the “%timeit” command, the particular code is specified after the “%timeit” is separated by a space.


2 Answers

The normal way to do this would be to simply write a python function, with a def. But if you want to alias a statement, rather than a function call, then it's actually a bit tricky.

You can achieve this by writing a custom magic function. Here is an example, which effectively aliases the import statement to get, within the REPL.

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)

Now it is possible to execute get statements which are aliased to import statements.

Demo:

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]: 

Of course, this is extendible to arbitrary python code, and optional arguments are supported aswell.

like image 146
wim Avatar answered Oct 01 '22 02:10

wim


I don't know since when IPython provides with macro. And now you can simply do this:

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

You can put this code into any file located in ~/.ipython/profile_default/startup/, and then this macro will be automatically available when you start IPython.

However, a macro doesn't accept arguments. So pleaes keep this in mind before you choose to define a macro.

like image 41
SleepyBag Avatar answered Oct 01 '22 03:10

SleepyBag