The REPL is your debugger that's always on
Most languages have an interactive shell of some sort, but in Python it's a first-class part of how the language is used day-to-day. Not a teaching toy. The REPL is where you sketch ideas before writing the file, where you debug live objects without restarting your program, where you confirm "does this method actually return what I think?" before committing to a refactor.
The version that ships with Python 3.13 finally got proper multi-line editing, syntax highlighting, and a much improved help/exit experience. If you're on 3.13+, you've already got it. If you're on 3.12 or earlier, this lesson covers what to install (ipython, bpython) to get the same quality of life.
Built-in features you probably missed
Even the plain python REPL has features most people never discover:
- Up/Down arrow walks through your input history. Hit up — your last expression comes back, editable.
- Tab completes attribute names, method names, even local variables. Type
str.and hit tab — Python lists every method on str. - The
_(underscore) variable always holds the result of the last expression evaluated at the prompt. So you can type2 + 2, then_ * 10on the next line, and get 40. Chains like this are the REPL's superpower. help(thing)opens the docstring for any object — function, class, module. Pressqto exit help.dir(thing)lists every attribute and method on an object. Less polished than help, but exhaustive.
help() with no argument enters Python's full interactive help system — the same docs as docs.python.org, browsable from the prompt. Useful when offline or when you don't want to context-switch to a browser.
Multi-line editing in 3.13
Pre-3.13 REPLs had a famous wart — once you started typing a multi-line block (a function definition, a for-loop), you couldn't go back and edit earlier lines. Mistype something on line 1 of a five-line function? Cancel and re-type from scratch.
Python 3.13's new REPL fixes this. You can up-arrow into earlier lines of an in-progress block, edit them, and execute the whole thing. F1 brings up the help system inline. F2 brings up history search. F3 toggles paste mode (so you can paste indented code without the auto-indenter fighting you).
python -i script.py — script then drop into REPL
One of the highest-leverage flags in the entire python command. python -i myscript.py runs the script normally — and when it finishes (or raises an unhandled exception), enters a REPL where the module globals defined so far remain available.
This is how you debug a script without setting up pdb or any IDE: It does not preserve the local variables of function frames that have already unwound. Use pdb.pm() or python -m pdb for post-mortem frame inspection; use -i for fast access to module globals.
python -i on a small repro script. A small reproduction can leave its module-level inputs and outputs ready for inspection. If the missing clue lives inside an unwound function, post-mortem pdb is the correct tool instead.
ipython and bpython — REPLs with superpowers
Even with 3.13's improvements, two third-party REPLs are worth knowing:
- ipython — the data science REPL. Magic commands (
%timeit,%run,%load), better tracebacks, automatic pretty-printing, and integration with Jupyter notebooks.pip install ipythonthenipythonlaunches it. Once you've used%timeitfor benchmarking, the plain REPL feels primitive. - bpython — lightweight, lovely UI, inline auto-suggestions as you type. Less feature-loaded than ipython, but more pleasant for casual exploration.
pip install bpython.
You don't need both. Pick one (most devs end up on ipython) and add it to your default install kit.
exec() and eval() — when, why, and the security note
Two built-in functions occasionally tempt beginners — eval(string) evaluates a Python expression, exec(string) executes Python statements. Both take a string and run it as code.
The temptation: "I want the user to type a math expression and get the answer" → eval(input()). The reality: that one line lets the user type __import__('os').system('rm -rf ~') and your machine catches fire.
eval or exec. Ever. If you find yourself reaching for them to parse user input, what you actually want is ast.literal_eval when the format is a Python literal (it does not evaluate arbitrary expressions or calls), or a real parser like pyparsing, or just json.loads if the input is JSON. eval on untrusted input is an arbitrary-code-execution vulnerability with extra steps. literal_eval can still exhaust memory or the C stack, so bound adversarial input size and depth.
That said, both functions have legitimate uses — runtime code generation, REPL implementations, dynamic class building. The Standard Library track will revisit them in context.
Bottom line
The REPL is not a beginner-only tool. Many seasoned Python developers spend more time in ipython than in their editor for exploratory work. Master the four basics (history, tab completion, _, help/dir), install ipython, and treat the REPL as your live debugger.
dir() and help() on it. The Pythonic answer to "how does this work?" is often "ask the object yourself."