Skip to content

magic_commands

Magic commands are one of the most powerful and convenient features of the IPython kernel, enhancing the interactive Python experience significantly. They provide shortcuts and extended functionalities beyond standard Python syntax, often used for controlling the environment, interacting with the operating system, timing code, and more.

Think of them as special commands prefixed with % or %% that IPython intercepts and processes directly.

There are two types of magic commands:

  • Line magics: Prefixed with a single %, they operate on a single line of input.
  • Cell magics: Prefixed with %%, they operate on the entire code cell below the magic command.

Line magics function similarly to command-line calls. The rest of the line after the magic command constitutes its arguments, often passed without parentheses or quotes (though quotes are needed for arguments containing spaces). Some line magics can return values that can be assigned to variables.

Cell magics apply to the entire multi-line content of the cell they are in. The magic command must be the very first thing in the cell. They can process the cell content in various ways – it doesn’t even have to be Python code (e.g., %%bash, %%html).

You can list all available magic commands using:

%lsmagic

To get help on a specific magic command, use ?:

%timeit?

A quick reference card for magics is available via:

%quickref

Runs an external Python script file within the current IPython namespace.

# Contents of my_script.py:
# message = "Hello from script!"
# print(message)
%run my_script.py
# Output: Hello from script!
print(message) # Variable defined in script is now available
# Output: Hello from script!

Loads code from an external script, URL, or history entry into the current cell for editing and execution.

# Cell 1:
%load my_script.py
# Cell 1 after execution becomes:
# %load my_script.py
message = "Hello from script!"
print(message)

Measures the execution time of a single Python statement (line magic).

%time my_list = [x**2 for x in range(10000)]
# Output: CPU times: user X ms, sys: Y ms, total: Z ms
# Wall time: W ms

Measures the execution time of a statement more accurately by running it multiple times. Available as both line and cell magic.

# Line magic
%timeit my_list = [x**2 for x in range(1000)]
# Output: X us +- Y ns per loop (mean +- std. dev. of Z runs, W loops each)
# Cell magic
%%timeit
my_list = []
for x in range(1000):
my_list.append(x**2)
# Output: Similar timing information for the entire cell

Displays previous commands entered during the session.

%history -n 1-3 # Show input lines 1 to 3

%who lists variables in the current namespace. %whos provides more detail (type, value/info).

a = 10
b = 'hello'
%who
# Output: a b
%whos
# Output:
# Variable Type Data/Info
# -----------------------------
# a int 10
# b str hello

%pwd prints the current working directory. %cd changes the directory.

%pwd
# Output: /home/user/myproject
%cd ../anotherproject
# Output: /home/user/anotherproject
%pwd
# Output: /home/user/anotherproject

Configures how Matplotlib plots are displayed. Common backends:

  • %matplotlib inline: Plots appear directly below the code cell that generated them (static images).
  • %matplotlib widget: Plots appear below the cell with interactive controls (requires ipympl installed).
  • %matplotlib notebook: Similar to widget, provides interactivity (older, sometimes less stable than widget).
  • %matplotlib qt / tk / etc.: Displays plots in separate windows using specified GUI toolkits (less common in notebooks).
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title("Sine Wave")
plt.show()
# Plot appears below this cell

Extremely useful when developing your own Python modules. It automatically reloads modules before executing code, so changes you make in external .py files are reflected without restarting the kernel.

%load_ext autoreload
%autoreload 2
import my_module # Import your custom module
# Now, if you edit my_module.py and save it,
# the changes will be picked up the next time
# you call a function from my_module without needing
# to restart or manually reload.

Lists, gets, or sets environment variables for the current session.

%env # List all
%env PATH # Get value of PATH
%env MY_VAR=my_value # Set MY_VAR (for this session only)

Convenient way to install packages directly from a notebook cell using the corresponding package manager associated with the current kernel.

%pip install requests
# or if using a conda environment:
# %conda install scikit-learn

Activates the interactive debugger (pdb or ipdb) after an exception occurs. Call it immediately after the cell that raised the error.

# Cell 1:
def my_func(x):
return 1 / x
my_func(0)
# Cell 2 (run immediately after Cell 1 fails):
%debug

IPython allows executing code in other languages or rendering different formats directly within cells:

%%bash
ls -l
echo "Hello from Bash!"
%%html
<h1>This is HTML</h1>
<p>Rendered directly in the output.</p>
%%javascript
console.log('Hello from JavaScript!');
alert('This runs in the browser console.');
%%writefile my_new_script.py
# This cell's content will be saved to my_new_script.py
print("This content is written to a file.")
def new_function():
return 'Success!'

This magic command imports many functions from NumPy and Matplotlib directly into the global namespace (e.g., you can call plot() instead of plt.plot()). While convenient for very quick interactive sessions, it is strongly discouraged for any serious work or scripts because:

  • It pollutes the namespace, making it unclear where functions come from.
  • It can lead to naming conflicts.
  • It makes code harder to read and understand.
  • It deviates from standard Python practices.

Best practice is to always use explicit imports:

import numpy as np
import matplotlib.pyplot as plt

You can define your own magic functions using decorators from IPython.core.magic.

from IPython.core.magic import register_line_magic
@register_line_magic
def greet(line):
"""A simple line magic that greets someone."""
name = line or 'World'
print(f"Hello, {name}!")
# Now you can use it:
%greet
# Output: Hello, World!
%greet Alice
# Output: Hello, Alice!

Magic commands are a cornerstone of the enhanced interactive experience provided by IPython and Jupyter, making many common tasks simpler and more efficient.