Unlock IPython's Magical Toolbox for Your Coding Journey

Unlock IPython's Magical Toolbox for Your Coding Journey

by Vincent Matinde Jul 12, 2023 basics editors tools

When you’re executing Python code, the standard Python shell that comes with your Python installation is a natural tool to use. However, as you progress in your coding journey, you might find yourself seeking more powerful functionalities than the standard REPL offers. Luckily, IPython offers an enhanced version of interactive Python that can supercharge your capabilities.

Using the IPython shell is a fast way of learning Python and executing code without the need for a full-fledged integrated development environment (IDE), such as PyCharm. IPython adds great features to the Python experience with its magic commands, which the standard Python shell lacks. These can help you complete tasks more quickly.

In this tutorial, you’ll:

  • Learn the major aspects and functionality of the IPython shell
  • Write and execute code in IPython
  • Integrate IPython in your Python scripts
  • Use IPython’s magic commands in your coding sessions
  • Learn how to save your sessions persistently in a Python file

To get started with IPython, you don’t need to be far along in your Python journey. In fact, IPython is an excellent learning tool because it offers an intuitive interface. Are you ready to get started?

Install and Initiate IPython on Your Machine

It only takes a few steps to install and initiate IPython. First, you’ll need to install Python on your system. You also might want to create and activate a virtual environment instead of installing IPython into your global Python.

To install IPython, use pip on the command line:

Windows Command Prompt
(venv) C:\Users\User>python -m pip install ipython

Just like that, you should see a message that the installation was successful. That means the package has installed all the dependencies, and you should be able to begin using the interactive shell. If you encounter any issues, please consult the documentation.

After the installation process is finished, you can initiate the interactive shell by executing the command ipython on the command line:

Windows Command Prompt
C:\Users\User>ipython
Python 3.11.4 (main, Jun 27 2023, 11:06:35) [Clang 14.0.0 (clang-1400.0.29.202)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.14.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

You’ll see the above message at the start of the session, confirming the successful installation of IPython on your machine. The shell initiates the first prompt, with In [1] indicating that it’s ready to accept input.

To exit the interactive shell, you can use the exit command, and you’ll switch from IPython to the command line. Now that you have IPython up and running, you’re ready to explore how it can transform your Python workflow. That’s what you’ll discover next.

Improve Your Interactive Python Workflow With IPython

The Python standard shell is a fantastic and versatile tool. However, IPython takes things up a notch by incorporating powerful features that can greatly enhance your coding productivity. While you can explore all of its strengths in the documentation, here are a few noteworthy distinctions that add up to a more user-friendly interface:

  1. Numbered prompts can give you a stronger understanding of the input code and output results.
  2. IPython has so many magic commands that the standard Python shell lacks, and they make working in the shell efficient.
  3. You can access your code history within the shell.
  4. It makes object introspection and code documentation accessible.

These advantages can make a huge difference in your life as a programmer. You’ll get to know these productivity boosters in the coming sections.

IPython is also available through Jupyter Notebooks. This browser-based interactive interface offers similar features, such as magic commands and numbered input and output. Its decoupled two-process model separates the front-end and back-end components of IPython into distinct processes. This allows the IPython kernel to function independently and handle code execution, namespace management, and communication between the shell and kernel.

The standard Python shell allows you to interact with Python on the command line. It permits you to enter statements or expressions one at a time. Then, it executes them and displays the corresponding output:

In the above code examples, you’re able to define two variables, first_name and last_name, and then concatenate the two strings. You can create mini-programs in the Python shell by creating other objects, such as functions and class objects.

The IPython interactive shell works similarly to the Python shell, but it offers a different code layout. Its interface is more expressive than the Python shell, thanks to its numbered input and output prompts, which you can see below:

Above, you start a new IPython session with the command ipython. You can then create variables within the shell. IPython numbers the variables that you’ve defined. Also, the concatenation of the two variables has produced an Out prompt. The code arrangement is more readable with the space separating the prompts.

But what exactly do those numbers mean? Next up, you’ll take a look at IPython’s input and output prompts, one of its key distinguishing features.

Understanding the Input and Output Prompts

One of the most notable differences between the IPython shell and the standard Python shell is the numbered inputs and outputs. You can call them input and output prompts. A prompt consists of one or more lines of code as input. If you get output, then it’ll have the same prompt number as the corresponding input.

To display the numbered inputs and outputs, define an employee profile by creating the following variables:

Python
In [1]: first_name = "Han"

In [2]: last_name = "Solo"

In [3]: department = "Accounts"

In [4]: f"{first_name} {last_name} works in {department}"
Out[4]: 'Han Solo works in Accounts'

In prompts 1, 2, and 3, you define the variables first_name, last_name, and department for the employee Han Solo. The three lines serve as input prompts where you can input or define variables.

In prompt 4, you use an f-string to concatenate the values of the variables. This produces an output line that displays the result of the concatenation. Output lines display the results of executed code or computations.

Compare the IPython shell to the standard Python shell interface:

Python
>>> first_name = "Han"
>>> last_name = "Solo"
>>> department = "Accounts"
>>> f"{first_name} {last_name} works in {department}"
'Han Solo works in Accounts'

The standard Python shell has no numbered input and output prompts. Instead, it uses >>> to represent prompts. Even though this doesn’t interfere with writing and executing code, the interactive shell has a more explicit interface with the help of the input and output prompts.

Overall, the breakdown of code into input and output prompts is more intuitive, which helps you understand and execute your code so that you can more effectively learn Python.

Using Tab Completion

Before you start exploring the functionality of the interactive shell, you’ll want to understand IPython’s tab completion assistance, which is quite different from what the standard shell offers. The IPython shell offers tab completion for any object when you type the first few characters of its name and press the Tab key:

In prompt 5, you enter the first letter of the department variable. When you press Tab, all of the built-in and user-defined objects that start with that letter appear, and you can use the Up, Down, Left, and Right keys to select the one that you intend to use. You then press the Enter button to load the object.

On the other hand, the standard Python shell would show a static list of matching symbols after hitting the Tab key twice.

When you’re working with large libraries or codebases, tab completion can be an efficient tool because you won’t have to scroll back to remember exact function or variable names as long as you know which object you want to use. This can be a time-saver and productivity hack that also reduces errors.

Applying Multiline Code in IPython

Writing multiline code in the standard Python shell can be time-consuming because you have to be aware of Python’s indentation-based syntax.

With the standard Python shell, you’ll have to manually indent each line of a code block with the correct amount of whitespace. For example, here’s how you define a salary_increment() function that adds a 10 percent increment to the employee’s salary within the standard Python shell:

You have to manually add four spaces to comply with Python’s indentation conventions when defining a function. If you forget to apply the indentation, then your code will produce an error, and you’ll have to define the function again.

It’s different in IPython, which automatically applies the indentation to the second and following lines of the function definition:

This is an advantage over Python’s standard shell. IPython will ensure that you don’t have to manually apply indentation after the first line of your function. IPython understands Python’s indentation-based block structure, so its user-friendly interactive shell does it for you.

Embed IPython Into Scripts

One unique feature of IPython is that you can embed it in existing Python scripts, which can offer valuable capabilities in your coding environment. This allows you to have an interactive session within your script, enabling you to explore and interact with variables and execute commands that you’ve defined in your Python file.

To do this, you’ll use the embed() function from the IPython module to launch an interactive session. Write the following code in a Python file named employee.py:

Python
 1# employee.py
 2
 3import IPython
 4
 5first_name = "Han"
 6last_name = "Solo"
 7department = "Accounts"
 8print(f"{first_name} {last_name}")
 9
10IPython.embed()
11
12salary = 1000

Take note of IPython.embed() in line 10. This function will start an IPython session once the execution reaches that line.

Now run the employee.py file like you would run any Python script. Python will execute all the lines of code until it reaches the call to embed(). Then you’ll enter an IPython shell:

Python
C:\Users\User>python employee.py
Han Solo
Python 3.11.4 (main, Jun 27 2023, 11:06:35) [Clang 14.0.0 (clang-1400.0.29.202)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.14.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: first_name
Out[1]: 'Han'

In [2]: last_name
Out[2]: 'Solo'

In [3]: salary
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Input In [3], in <cell line: 1>()
----> 1 salary

NameError: name 'salary' is not defined

The call to print() from line 8 in your script executes and displays the output, Han Solo, to your terminal. Then the interactive shell launches. To see it in action, you access some variables from your file.

In prompts 1 and 2, the first_name and last_name variables that you defined in the employee.py file are available in the namespace. However, variables that you defined after the embed() function, like salary, aren’t available in the namespace, as you can see in prompt 3. This ensures that you only work with variables that you want to import into your namespace.

It’s good to note that this technique is quite useful in post-mortem debugging, as it allows you to inspect the state of your program after it crashes. If you have an undesirable output in your Python file, then you can use the IPython shell to experiment with your variables and objects and pinpoint the issue without interfering with your Python file.

Become a Power User With IPython Magic Commands

You’ve already learned about several of IPython’s advantages over the standard Python shell, and you haven’t even touched magic commands yet! The standard Python shell doesn’t have its own commands, so the aptly named magic commands give IPython an edge over other REPLs.

Magic commands will usually begin with the percent sign (%). Prefixing a command with a single percent sign will apply the command to one line in your code. However, if you use the double percent sign (%%), it’ll apply the command to the whole prompt, which can consist of more than one line of code and is then called a cell.

You have the option of not using the percentage prefix with the magic commands. For beginners, it’s a good idea to use it anyway because it makes commands clear in your prompts, ensuring that the code flow makes sense. However, you can opt to go without it once you get comfortable with IPython commands. Later, you’ll learn how to turn the magic command prefix on and off.

You’ll now learn about several magic commands that will enable you to move within folders, load external data into the shell, list variables, and even export the code within the IPython shell to an external Python file.

Within the IPython shell, you can navigate your file system just like in the regular Unix shell. With the %pwd command, you can display where you currently are within the file system. This is similar to the Unix shell’s built-in pwd command:

Python
In [1]: %pwd
Out[1]: '/Users/vincentmatinde'

With the output obtained from this command, you can confidently determine the specific directory that you’re currently working in. This gives clarity regarding your file and directory navigation. It’s also valuable when you’re building a complex project or working with multiple directories simultaneously.

To list the files and directories in your current location, you can use the %ls command:

Python
In [2]: %ls
Applications/   Downloads/    Movies/       Pictures/
Desktop/     Public/    Documents/    Library/

The %ls command lists all the directories within your current location, which is helpful for quickly inspecting the contents of a directory without leaving the IPython environment.

You can navigate your machine’s file structure from inside IPython with the %cd command. It’s similar to the cd command that you’d use on the command line:

Python
In [3]: %cd Documents
/Users/vincentmatinde/Documents

Here, you go into the Documents folder. Note how the prompt gives the file path to show that your command was successful.

By combining the three commands for traversing the file system on your machine, the interactive shell makes locating files or folders quite straightforward.

But what if you don’t want to go through your file structure to get to your favorite directory? IPython’s got you covered, as you’ll learn next.

Bookmarking Working Directories

If you’d like to go to your preferred directory without traversing your file structure, then the bookmark feature will come in handy. For example, you could bookmark the folder that contains your employee.py file. You use the syntax %bookmark <bookmark-name> <directory> to create a bookmark:

Python
In [1]: %bookmark Employees /Users/vincentmatinde/Documents/Employees

Here, you’ve created an Employees bookmark corresponding to the relevant folder’s name. Notice how you included the path to the folder that you wanted to bookmark.

Once you’ve created your bookmark, you can jump to that folder, regardless of your current location, by using the %cd -b Employee command:

Python
In [2]: %cd -b Employees
(bookmark: Employees -> /Users/vincentmatinde/Documents/Employees
/Users/vincentmatinde/Documents/Employees

In [3]: %pwd
Out[4]: '/Users/vincentmatinde/Documents/Employees

When you jump to the directory that you’ve bookmarked, you can confirm your location by using the %pwd command, as you did in prompt 3.

You can have as many bookmarks as you’d like. Use the same commands as above to create other bookmarks, such as Contacts and Departments. To list all of your bookmarks, use the %bookmark -l command:

Python
In [5]: %bookmark -l
Current bookmarks:
Contacts    -> /Users/vincentmatinde/Documents/Contacts
Departments -> /Users/vincentmatinde/Documents/Departments
Employees   -> /Users/vincentmatinde/Documents/Employees

The list of bookmarks will display the name that you gave to each bookmark, followed by the directory path that the bookmark points to. This makes it relatively painless to track all the working directories within your sessions. It also helps you pick up quickly in a new session, without manually tracking files.

Finally, if you want to delete any bookmarks, then you can use the %bookmark command followed by the flag -d, for delete, and the bookmark name:

Python
In [6]: %bookmark -d Contacts

In [7]: %bookmark -l
Current bookmarks:
Departments -> /Users/vincentmatinde/Documents/Departments
Employees   -> /Users/vincentmatinde/Documents/Employees

There’s no explicit feedback confirming that you’ve deleted the targeted bookmark. However, when you check the list of bookmarks in prompt 7, it’s no longer available because you’ve removed it from the namespace.

It’s a good practice to name your bookmarks according to the project that you’re working on. Having multiple bookmarks can cause confusion in your namespace if they’re not labeled appropriately.

Loading File Inputs Into a Shell Session

Remember how you can load IPython into your Python script? Well, you can also go the other way and load the contents of a Python file into the interactive shell. The %load command loads the contents of a file into an IPython session. This means that you don’t have the hassle of copying and pasting code from a file into your interactive session.

Start a new IPython session and use the employee.py file that you created earlier. To avoid confusion, delete the IPython import and the IPython.embed() line. Your file should look like this:

Python
# employee.py

first_name = "Han"
last_name = "Solo"
department = "Accounts"
salary = 1000

Ensure that you’re in the directory that has the file you want to load, or you can provide a path to it. To load the contents of the file into the IPython session, you use the %load command:

Python
In [1]: %load employee.py

In [2]: # %load employee.py
   ...: first_name = "Han"
   ...: last_name = "Solo"
   ...: department = "Accounts"
   ...: salary = 1000
   ...:

In [3]: first_name
Out[3]: 'Han'

In [4]: last_name
Out[4]: 'Solo'

With one command, you’ve loaded the contents of the Python file, and you can now use it in your session. All the variables from the file are now available in the session’s namespace, as you confirm in prompts 3 and 4. This is another practical way to test and play around with variables and functions that you’ve defined in your other Python files.

Next, you’ll learn how to list all the variables defined in the namespace, giving you an overview of the variables currently present and accessible in your code.

Listing Variables in the Namespace

In addition to using tab completion to list variables, you have the option of using the commands %who or %whos to get additional information about the variables that you’ve defined yourself. Tab completion displays all objects, regardless of whether they’re system- or user-defined. On the other hand, the %who command specifically lists your variables.

Below, the interactive shell gives you a list of the variables that you’ve previously defined:

Python
In [5]: %who
department   first_name  last_name   salary

In prompt 5, the %who command lists all the previously defined variables. It’s important to note that the variables are listed in alphabetical order. This command serves as a convenient way to verify the variables that you’ve already defined in your namespace.

However, there may be instances where this information alone isn’t sufficient. That’s why the %whos command will provide more helpful information about the variables that you’ve defined in your session:

Python
In [6]: %whos
Variable     Type    Data/Info
------------------------------
department   str     Accounts
first_name   str     Han
last_name    str     Solo
salary       int     1000

You can now examine the type and corresponding value of each variable, allowing you to determine the variable types. This information enables you to work efficiently when dealing with variables.

Clearing Variables in IPython

You can reset variables or, ideally, delete them from your namespace by using the %reset_selective command. You can do this by adding the name of the object or variable as an argument. Sticking to the previous code, you can target the variable salary:

Python
In [7]: %reset_selective salary
Once deleted, variables cannot be recovered. Proceed (y/[n])?  y

In [8]: salary
--------------------------------------------------------------------
NameError                          Traceback (most recent call last)
<ipython-input-10-55b5c721c8d2> in <module>
----> 1 salary

NameError: name 'salary' is not defined

When you use the %reset_selective command on the salary variable, you delete it from the namespace. You’ll receive a confirmation prompt to proceed with the deletion. In prompt 8, when you try to access the salary variable, it results in a NameError.

If you want to get a clean slate in your session without closing the command prompt or exiting the interactive shell, then you can clear the variables in the namespace with the %reset command. This command will remove all user-defined variables, functions, and imported modules, so be careful when initiating this command:

Python
In [9]: %reset
Once deleted, variables cannot be recovered. Proceed (y/[n])? y

In [10]: %who
Interactive namespace is empty.

The %reset command has removed all the variables in the session. In prompt 10, when you use the %who command, you get a message that the interactive namespace is empty. You can now define new variables in the namespace.

You can also use the reset command with the -f flag, which stands for force, to bypass the confirmation stage. The %reset -f command will delete the variables in the session without asking for confirmation, so use it with care.

Scanning Code History

Sometimes it’s useful to go back and revisit your previous code, but combing through all the input and output can be a chore. IPython has a handy magic command, %history, which will display previously executed commands in the current session. It allows you to review and access past commands, making it convenient for recalling snippets:

Python
In [11]: %history -n
   1: %load employee.py
   2:
# %load employee.py
# employee.py

first_name = "Han"
last_name = "Solo"
department = "Accounts"
salary = 1000
   3: first_name
   4: last_name
   5: %who
   6: %whos
   7: %reset_selective salary
   8: salary
   9: %reset
  10: %who
  11: %history -n

Executing the %history command without any arguments will display all the commands, including the inputs that you’ve used so far. It won’t show the code prompt numbers, though. When you use the optional -n parameter, it’ll enumerate the displayed entries, making it easier for you to refer to past commands later.

If you want to see a specific history item, then you can use the number of the prompt as an argument. This will prove useful for recently entered prompts as long as you can remember their contents:

Python
In [12]: %history 7
%reset_selective salary

You’ve accessed a previous input from prompt 7, where you called %reset_selective on the salary variable. If you wish to rerun a specific code block, then you can utilize the %recall command, which reloads the designated prompt and executes its contents. But first, load the employee.py file to get all the variables back in the namespace. You can list them to get the sample code that you can call again:

Python
In [13]: %load employee.py

In [14]: # %load employee.py
    ...: first_name = "Han"
    ...: last_name = "Solo"
    ...: department = "Accounts"
    ...: salary = 1000
    ...:

In [15]: first_name
Out[15]: 'Han'

In [16]: last_name
Out[16]: 'Solo'

In [17]: department
Out[17]: 'Accounts'

So now you can use the %recall command with any of the prompts to rerun the specific commands from a prompt:

Python
In [18]: %recall 15

In [19]: first_name
Out[19]: 'Han'

Once you recall prompt 15, the code is available to use in the next line. This can work for other objects, such as functions, if you’d like to reuse them. This command supports the Don’t Repeat Yourself (DRY) software development principle because you’re recalling a variable without rewriting it.

It can be difficult to remember the contents of an earlier prompt. However, you can commit important prompts to memory when you know that you’ll reuse them throughout your session. Then recalling them can be a time-saver.

Clearing Your Workspace

Working for a long time in the shell can mean there’s a lot of code in your IPython session. But what if you want to remove the clutter and start with a clean screen? That’s where another magic command comes into play. To clear the output from the current IPython session, you can use another magic command. This command is handy when you want to remove the clutter and start with a clean screen.

The command is different depending on whether you’re on a Windows or Unix system:

On Windows systems, the command is %cls, which utilizes the built-in cls command of the Windows Terminal to clear the screen.

For Unix-based systems, like Linux and macOS, you can use %clear to clear the screen. When executed, it clears the output and provides a fresh workspace.

After executing the magic command, you’ll notice that the previous output from your IPython session is no longer visible:

You have a clean screen ready for new commands and interactions. It’s important to note that this command only clears the output within IPython and doesn’t affect the command history or any variables or functions that you’ve defined unless you start a new IPython session.

Storing Variables in Sessions

When you need to preserve data between two sessions without saving it to a Python file, the %store command can help. You won’t have to restate all of your variables and objects when you start a new session.

To store a variable, you can use the %store command and then the variable name:

Python
In [20]: %store first_name
Stored 'first_name' (str)

In [21]: exit

In this example, you store the first_name variable and then exit the interactive shell in prompt 21. When you start a new session, you should be good to go, right? But watch what happens when you try to access first_name in a new session:

Python
In [1]: first_name
--------------------------------------------------------------------
NameError                          Traceback (most recent call last)
Input In [1], in <cell line: 1>()
----> 1 first_name

NameError: name 'first_name' is not defined

You get a NameError. That would make sense if you hadn’t saved the variable, but you preserved it for access between sessions using the %store command. However, there’s a corresponding command that you need to use to restore the variable in a new session:

Python
In [2]: %store -r

In [3]: first_name
Out[3]: 'Han'

In your new session, you’ve restored the variable using the %store command with the -r flag for reload. In prompt 3, you confirm that the first_name variable is now accessible in the new namespace.

You can also chain several variables that you’d like to save between sessions if you have specific variables crucial to your project. Add the variables last_name, department, and salary, and then call %store:

Python
In [4]: last_name = "Solo"

In [5]: department = "Accounts"

In [6]: salary = 1000

In [7]: %store last_name department salary
Stored 'last_name' (str)
Stored 'department' (str)
Stored 'salary' (int)

After you initiate the %store command with all the variables that you’d like to store, the terminal will list all the stored variables for your information and their types. You can then use the %store -r command to restore all the variables in a new session. Calling %store in a new session without any variables will only list all the stored variables.

You can delete a variable from storage using the %store -d <variable_name> syntax. With this command, you can remove any variable from storage that you don’t want to persist between sessions.

Understanding Objects Through Introspection

Object introspection is one of IPython’s notable strengths. By using the ? or ?? suffix immediately after an object, such as a variable or function, you can access data about the object. You can also do this with some of the IPython commands to gain insights about them!

The single ? allows you to quickly skim through the values and the type of any object and its documentation, giving you quick information right in the IPython shell. In your IPython session, add the salary_increment() function that you defined earlier:

Python
In [8]: def salary_increment(salary):
   ...:     """Calculate the new salary after applying an increment.
   ...:     Args:
   ...:         salary (int): The current salary.
   ...:     Returns:
   ...:         str: A string indicating the new salary after increment.
   ...:     """
   ...:     increment = salary / 10
   ...:     new_salary = increment + salary
   ...:     return f"Your New Salary is: {new_salary}"
   ...:

With the code above, you display the function that you defined earlier to calculate a salary increment. The function also has a docstring to explain what the function is meant to do. Docstrings are a useful way to document code. For now, they’ll help you analyze the function in the next line:

Python
In [9]: salary_increment?
Signature: salary_increment(salary)
Docstring:
Calculate the new salary after applying an increment.
Args:
    salary (int): The current salary.
Returns:
    str: A string indicating the new salary after increment.
File:      c:\users\user\<ipython-input-9-8b992f8ebfc4>
Type:      function

The introspection command returns the docstring, its required arguments, and other information about the object. It also states the object’s type. In this case, it’s a function.

That might be enough for your purposes, or maybe you’d like even more information. With the ?? symbol, you can access the source code and documentation:

Python
In [10]: salary_increment??
Signature: salary_increment(salary)
Source:
def salary_increment(salary):
    """
    Calculate the new salary after applying an increment.

    Args:
        salary (int): The current salary.

    Returns:
        str: A string indicating the new salary after increment.
    """
    increment = salary / 10
    new_salary = increment + salary
    return f"Your New Salary is: {new_salary}"
File:      c:\users\user\<ipython-input-9-8b992f8ebfc4>
Type:      function

You can now view the source code of the function in addition to the docstring and type that the single ? prefix gave you. This can give you a more in-depth analysis of the objects that you’re interested in.

While learning your way around the IPython shell, you can use both ? and ?? to get information on the magic commands that you’ve discovered in this tutorial. For example, you can check on the %who command:

Python
In [11]: %who?
Docstring:
Print all interactive variables, with some minimal formatting.

If any arguments are given, only variables whose type matches one of
these are printed.  For example::

  %who function str

will only list functions and strings, excluding all other types of
variables.

(...)

Your understanding of functions and objects will become clearer when you can access the documentation, description, and source code for all objects. This applies to all the objects that you’ll encounter as you study Python and third-party libraries, accelerating your learning process by accessing their documentation within the IPython shell.

Saving Code Into a File

You can save all your code from the interactive shell to a Python file in full or in part with the %save command. If you use the command with an arbitrary filename, then you’ll save all the code in your session to the file. Below, you use a file named employee_draft:

Python
In [12]: %save employee_draft
The following commands were written to file `employee_draft.py`:
first_name
get_ipython().run_line_magic('store', '-r')
first_name
last_name = "Solo"
department = "Accounts"
salary = 1000
get_ipython().run_line_magic('store', 'last_name department salary')
def salary_increment(salary):
    """Calculate the new salary after applying an increment.
    Args:
        salary (int): The current salary.
    Returns:
        str: A string indicating the new salary after increment.
    """
    increment = salary / 10
    new_salary = increment + salary
    return f"Your New Salary is: {new_salary}"
get_ipython().run_line_magic('pinfo', 'salary_increment')
get_ipython().run_line_magic('pinfo2', 'salary_increment')
get_ipython().run_line_magic('pinfo', '%who')

By using the %save command, you write all your code in the namespace to a Python file with the name that you gave with the command. Note that the resulting Python file will be located in the same directory where you currently are. To ensure that you save it in the right directory, use your old friend %cd to move to the desired directory or %bookmark if you’ve created a bookmark for your project.

You’ll notice that there are unnecessary commands that might not be relevant to your project. For example, lines starting with get_ipython() might not be useful. You can delete these lines in your file and just keep the useful code. However, there’s a more straightforward way to do this.

If you don’t want to save all your code in a Python file, then you can specify a set of input prompts from your session that you want to save to a file:

Python
In [13]: %save employee_draft 4 5 6 8
File `employee_draft.py` exists. Overwrite (y/[N])?  y
The following commands were written to file `employee_draft.py`:
last_name = "Solo"
department = "Accounts"
salary = 1000
def salary_increment(salary):
    """Calculate the new salary after applying an increment.
    Args:
        salary (int): The current salary.
    Returns:
        str: A string indicating the new salary after increment.
    """
    increment = salary / 10
    new_salary = increment + salary
    return f"Your New Salary is: {new_salary}"

In the above code, you’ve specified which prompts you’d like to save to a file. These are 4, 5, 6, and 8, which hold variables and the salary_increment() function. Now you’re not saving unnecessary code from IPython in the file. Notice that if you specify the same filename or the name of an existing file, then IPython will overwrite the content of that file.

Turning the Magic Command Prefix On and Off

So far, you’ve decorated the magic commands with the % symbol. The percent sign is particularly useful in clearly showing what’s a command and not part of the code.

However, it’s possible to use the commands without the prefix. This is because the %automagic command is on by default, freeing you to use the commands without the magic prefix:

Python
In [14]: history
first_name
%store -r
first_name
last_name = "Solo"
department = "Accounts"
salary = 1000
%store last_name department salary
def salary_increment(salary):
    """Calculate the new salary after applying an increment.
    Args:
        salary (int): The current salary.
    Returns:
        str: A string indicating the new salary after increment.
    """
    increment = salary / 10
    new_salary = increment + salary
    return f"Your New Salary is: {new_salary}"
salary_increment?
salary_increment??
%who?
%save employee_draft
%save employee_draft 4 5 6 8
history

With the code above, you execute the history command without the % prefix. If you turned off automagic, then you’d receive an error.

To require the percentage prefix, you can use %automagic off:

Python
In [15]: %automagic off

Automagic is OFF, % prefix IS needed for line magics.

In [16]: history
--------------------------------------------------------------------
NameError                          Traceback (most recent call last)
Input In [19], in <cell line: 1>()
----> 1 history

NameError: name 'history' is not defined

When you turn off automagic, the % prefix is required on all magic commands. If you don’t provide it, then the code execution will result in a NameError, as you can see above.

As you learned earlier, it’s a good practice to use the prefix because it separates magic commands from your code. However, you can use the magic commands without the prefix if you get comfortable in the interactive shell.

You’ve now gained the knowledge to work in the IPython shell, aided by its powerful magic commands. You’ll definitely experience the advantages and power that IPython offers you as a developer.

It’s important to note that you’ve only learned a handful of magic commands in this tutorial. You can explore more magic commands by referring to the official documentation. If you want to check the documentation from your interactive shell, then you can execute the %quickref command for a quick reference guide or the %magic command for more details.

Conclusion

Your solid understanding of how to use IPython in your development workflows will pay off. You can now move between directories, bookmark your working directories, introspect objects, and export your code into an external Python file.

In this tutorial, you’ve learned how to:

  • Install and launch IPython on your machine
  • Differentiate IPython from the standard Python shell
  • Integrate the IPython shell into your programs
  • Save your IPython sessions in a Python file
  • Use magic commands to power your coding sessions and make you more efficient

Hopefully, the IPython interactive shell makes all your development dreams come true. But there are other options. You might also want to play with bpython and the standard REPL to boost your understanding of these environments.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Vincent Matinde

Vincent Matinde is a Python developer with a strong passion for coding and problem-solving. Over the past four years, he has immersed himself in the world of Python including data analytics, and web development.

» More about Vincent

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.


Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Tutorial Categories: basics editors tools