PYTHON / GETTING STARTED
The interactive interpreter and REPL workflow
Use Python's interactive prompt to test ideas: read >>> and ... prompts, know why expressions echo but assignments don't, reuse _, and inspect objects live.
What you will learn
- Tell >>> from ... and close an indented block by pressing Enter on an empty line
- Explain why x = 5 echoes nothing while x echoes 5, via sys.displayhook and repr
- Reuse the last echoed value through _ and inspect objects with type, dir and help
- Run python -i script.py to land at the prompt with that file's names loaded
Understanding The interactive interpreter and REPL workflow
The interactive prompt is itself a small program running a loop: it reads what you type, compiles it in "single" mode, executes it, and then hands any resulting value to sys.displayhook, which prints repr(value) and stores it in the builtin name _. Everything surprising about the prompt follows from that last step. Typing 2 + 3 shows 5 with no print() call because an expression statement produces a value; typing x = 5 shows nothing because an assignment produces no value; typing print("hi") shows only hi because print returns None and displayhook deliberately skips None.
The second prompt, ..., exists because after every Enter the loop must decide whether it has a complete statement yet. It joins the lines you have typed so far with newlines and passes the result to codeop.compile_command, which answers "complete", "not finished yet", or "broken". A for header on its own is not finished, so the loop keeps reading; the empty line you press at the end of a block is what appends the trailing newline that makes the joined source compilable, which is the real reason blocks need a blank line. A genuinely invalid line such as 2 + is not treated as unfinished at all and raises SyntaxError immediately.
In practice the prompt is for questions that fit on one line and files are for anything you want tomorrow: does this slice include the endpoint, what does this method return on an empty string, what attributes does this object have. Because names persist for the whole session in a single namespace, you can build up state step by step, then promote what worked into a .py file. Starting python -i script.py runs the file and then drops you at the prompt with everything the file defined still alive, which saves retyping setup code while you poke at it with type(), dir() and help().
import builtins
import sys
# These calls are exactly what the prompt does after evaluating each line you type.
sys.displayhook(2 + 3) # you typed: 2 + 3
sys.displayhook("tab\there") # repr(), so escapes stay visible
sys.displayhook(None) # print() returns None, so nothing is echoed
print("_ still holds", repr(builtins._))The prompt compiles each complete input in "single" mode and routes non-None results through sys.displayhook, which is why expressions echo their repr interactively but not in a script.
Worked examples
Driving a real REPL from a script
Feeds a canned session to code.InteractiveConsole so you can watch when the prompt switches to ... and when a value is echoed.
from code import InteractiveConsole
session = ["x = 6", "x * 7", "if x > 5:", " print('plenty')", ""]
console = InteractiveConsole()
prompt = ">>> "
for line in session:
print(f"{prompt}{line}".rstrip())
prompt = "... " if console.push(line) else ">>> "Example explained
Line 1InteractiveConsole is the same read-eval-print machinery the python command uses; here you supply the lines instead of a keyboard.
Line 2push() returns True when the buffered source is not yet a complete statement, which is exactly when the real prompt shows ... instead of >>>.
Line 342 appears with no print() because x * 7 was compiled in "single" mode and its value went to sys.displayhook.
Line 4The empty string is the blank line you press Enter on; only after it does the if block compile and its body run.
Why a block needs that blank line
Asks codeop.compile_command the same question the prompt asks after every Enter: complete, incomplete, or invalid.
from codeop import compile_command
def status(source):
try:
code = compile_command(source, "<input>", "single")
except SyntaxError:
return "invalid, reported immediately"
return "incomplete, keep reading" if code is None else "complete, run it"
print(status("total = 2 + 3"))
print(status("for i in range(2):"))
print(status("for i in range(2):\n print(i)"))
print(status("for i in range(2):\n print(i)\n"))
print(status("2 +"))Example explained
Line 1compile_command returning a code object means the prompt can execute now and go back to >>>.
Line 2Returning None means incomplete, so the loop keeps buffering lines and shows the ... prompt.
Line 3The third and fourth calls differ only by a trailing newline, which is what pressing Enter on an empty line contributes to the buffer.
Line 4For "2 +" the error is raised at once: a broken line is never mistaken for an unfinished one.
Interrogating an object without leaving the prompt
Shows the three questions worth asking at the prompt: what is this, what does it document, and what can it do.
def area(w, h):
"""Return the area of a w by h rectangle."""
return w * h
print(type(area))
print(area.__doc__)
print([n for n in dir("repl") if n.startswith("is")])Example explained
Line 1type(area) answers what kind of object a name is currently bound to, which is the first thing to check when a call fails.
Line 2area.__doc__ is the exact text help(area) would page for you; help() is a formatter over docstrings, nothing more.
Line 3dir("repl") lists the attribute names reachable on a str, filtered here to the is* predicates so the output stays readable.
Important notes
_ is set by the interactive displayhook only, and the very next echoed value overwrites it, so assign anything you want to keep to a real name.
In CPython 3.12 and earlier, typing exit without parentheses only prints a hint; use exit(), quit(), Ctrl-D on Unix, or Ctrl-Z then Enter on Windows.
Common mistakes
Copying the >>> or ... characters along with the code from a transcript: the interpreter parses them as source and you get SyntaxError: invalid syntax.
Expecting a .py file to echo values like the prompt: a file whose last line is just total prints nothing, because only interactive input passes through sys.displayhook, so the value is computed and discarded.
Never pressing Enter on an empty line after an indented block: the ... prompt keeps waiting, the loop body never runs, and it looks like the interpreter has hung.
Try it yourself
Change, predict, then run
In the editor, import sys and builtins, call sys.displayhook on 10 * 4, then on [1, 2], then on None, and finally print builtins._ with a comment explaining why it is not None.
Open the Python workspaceCheck your understanding
A file calc.py contains the single line 2 + 3. Running python calc.py prints nothing, but typing 2 + 3 at the prompt prints 5. What accounts for the difference?
- File code is compiled in exec mode, which discards the value of an expression statement; only interactive input is compiled in single mode and routed through sys.displayhook
- 2 + 3 is not a valid statement inside a file, so Python skips the line entirely
- The value is printed but stdout stays buffered until the process exits, at which point it is dropped
- Scripts always need print() because arithmetic on integers returns None outside the prompt
Show answer
The prompt compiles your input in "single" mode, which adds a step that hands each expression's value to sys.displayhook; a script is compiled in "exec" mode, where the value of an expression statement is simply popped and thrown away. Option 2 is tempting but wrong: 2 + 3 is a perfectly valid expression statement in a file, it really is evaluated, the result is just never displayed.