Learn How to Get Output in Python: Absolute Beginners Tutorial

When a Python script runs and produces no output, there is no way to know if it worked. print() is how a program speaks. This tutorial covers how to produce output in Python from your very first print() call through f-strings, separators, and line endings — building not just syntax knowledge, but a mental model of what the interpreter is actually doing at each step.

Producing output is how a program communicates. Without it, a script can run perfectly but leave no trace. Python makes this straightforward through the built-in print() function, which works from the first line you ever write and scales to cover formatted multi-line reports. This tutorial walks through every piece of that function so you understand not just what to type, but why each part works the way it does.

Key Concepts Glossary

These terms appear throughout the tutorial. Having names for these ideas gives you language to think with — and to search with when you encounter them again in documentation or error messages.

stdout Standard Stream
The default destination for print() output. "Standard output" is one of three streams every process has (the others are stdin for input and stderr for errors). When you see output in your terminal, it came through stdout. Understanding this name helps when you read error messages or redirect output in shell scripts.
Keyword Arguments Function Concept
Arguments passed to a function by name rather than position. sep and end in print() are keyword arguments — you write sep="-", not just "-". This pattern appears in every Python function that has optional parameters. Recognizing it here lets you read any function signature with confidence.
Type Coercion vs. Explicit Conversion Type System
Some languages silently convert values between types (coercion). Python does not — it requires you to convert explicitly using functions like str(). This is why print() can accept integers directly (it converts internally) but the + operator cannot join a string and an integer (it has no conversion rule for mismatched types).
String Interpolation Formatting
The general term for embedding variable values inside a string. f-strings are Python's string interpolation feature. Other languages have equivalents: template literals in JavaScript, string interpolation in Ruby. Knowing the general term helps you search documentation and map the concept across languages.
Built-in Function Python Internals
A function that is always available in Python without importing anything. print(), str(), len(), and input() are all built-ins. They live in a special module called builtins that Python loads automatically. When Python can't find a name, it checks this module last before raising a NameError.
Escape Sequence String Syntax
A two-character combination starting with a backslash that represents a character that cannot easily be typed directly in a string literal. \n is a single newline character; \t is a single tab. The backslash "escapes" the normal meaning of the character that follows it. The same mechanism appears in file paths, regular expressions, and network protocols.

The print() Function

The print() function is built into Python, meaning you never need to import anything to use it. You call it by typing its name followed by parentheses, and you place whatever you want to display inside those parentheses. Python's official documentation describes print() as sending its arguments to the standard output stream, which in practice means your terminal window.

The complete signature of print(), as documented by the Python Software Foundation, is:

python
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Every parameter except *objects has a default. That is why print("hello") works — you are relying on every default at once. The parameters you will use at this stage are sep (the separator between values), end (what to print at the end of the call), file (where to send output — defaults to the terminal), and flush (whether to force the output buffer to empty immediately — added in Python 3.3, defaults to False). Each is covered in context through this tutorial.

What's Actually Happening

When Python runs print("Hello, world!"), it looks up print in the builtins module, calls it as a function, and internally calls sys.stdout.write() to send the text to the terminal. The newline you see at the end is added by print() itself — it's the end="\n" default. This is why print() and sys.stdout.write() are equivalent, except that sys.stdout.write() adds no newline and returns a character count instead of None.

python
print("Hello, world!")

Running that single line produces:

output
Hello, world!
Note

String literals inside print() can use single quotes ' or double quotes ". Both produce identical results. Choose whichever you prefer and stay consistent within a project.

Printing Numbers and Empty Lines

You can pass integers and floats directly to print() without wrapping them in quotes. Python converts numeric values to their string representations automatically. Calling print() with nothing inside produces a blank line, which is useful for spacing output.

python
print(42)
print(3.14)
print()
print("After a blank line")
output
42
3.14

After a blank line
Pro Tip

Readable output is important for debugging. Insert blank lines between sections of printed data while developing to quickly spot where different parts of your program start and stop.

Connecting Forward

print() is a function call — the same syntactic pattern you will use for every function in Python, built-in or custom. The parentheses, the arguments inside them, and the way Python evaluates them left to right are all universal. What you learn here about calling print() applies directly to calling any other function.

code builder click a token to place it

Build a valid Python statement that prints the text Hello, Python! to the screen:

your code will appear here...
("Hello, Python!") input print ["Hello, Python!"] display
Why: The correct function is print, not input or display — those are either a different function or not a Python built-in. Arguments go inside parentheses (), not square brackets []. The string must be in quotes inside the parentheses.

Printing Variables and Multiple Values

Programs rarely print fixed text only. Usually you need to display the result of a calculation or the current value of a variable. You pass a variable to print() the same way you pass a string — just use the variable name without quotes.

python
name = "Alex"
age = 29
print(name)
print(age)
output
Alex
29

The sep Parameter

Pass multiple values to print() by separating them with commas. Python places a single space between each value by default. The sep parameter lets you replace that space with any string you choose, including an empty string to remove spacing entirely.

python
# Default sep is a single space
print("Python", "is", "fun")

# Custom sep
print("2026", "04", "03", sep="-")

# No spacing between values
print("http", "//", "example.com", sep="")
output
Python is fun
2026-04-03
http//example.com

The end Parameter

By default, print() adds a newline character at the end of every call, so the next call starts on a fresh line. The end parameter replaces that newline with any string you specify. Setting end="" keeps all output on the same line.

python
# Default end (newline after each call)
print("Line one")
print("Line two")

# Same line using end=""
print("Loading", end="")
print("...", end="")
print(" done")
output
Line one
Line two
Loading... done
Default value
A single space character " "
Common use
Formatting dates, paths, or lists where you need a specific delimiter between multiple printed values in a single call.
Default value
A newline character "\n"
Common use
Building progress indicators, same-line updates, or suppressing the automatic newline when constructing output piece by piece across multiple calls.
Example
print("a", "b", "c", sep="|", end="!\n") produces a|b|c! followed by a newline.
Why it matters
Both parameters are keyword arguments and can appear in any order, but both control entirely separate parts of the output: one governs spacing between items, the other governs what the entire call ends with.
predict the output read the code, then guess what prints

What does the following code print? Run it in your head before selecting an answer.

python
print("A", "B", "C", sep="|", end="!\n")
print("done")
Why B: sep="|" places a pipe between each value, producing A|B|C. end="!\n" replaces the default newline with ! followed by an explicit newline — so the first line ends with !. The second print("done") starts fresh on a new line with its own default end="\n".
spot the bug click the line that contains the bug

The code below is supposed to print "2026-04-03" but something is wrong. Click the line you think contains the bug, then hit check.

1 year = "2026"
2 month = "04"
3 print(year, month, "03", sep=" ")
4 print("Done")
The fix: Change sep=" " to sep="-". The goal is to join the three date parts with a hyphen, but a space was used instead, producing 2026 04 03 rather than 2026-04-03.

Escape Sequences and Multi-Line Output

String literals in Python support escape sequences — special two-character combinations that start with a backslash and represent characters that would otherwise be difficult or impossible to type directly inside a string. Beginners encounter them constantly because print() uses them internally for its own defaults.

The two you will see most often are \n (newline) and \t (tab). They can appear anywhere inside a string passed to print().

python
# \n inserts a newline inside a string
print("Line one\nLine two\nLine three")

# \t inserts a tab stop
print("Name:\tJordan")
print("Score:\t98")
output
Line one
Line two
Line three
Name:	Jordan
Score:	98
Note

When end="\n" is the default for print(), that \n is the same newline escape sequence. Understanding escape sequences explains why changing end controls line breaks.

Triple-Quoted Strings for Multi-Line Output

When you need to print a long block of text across multiple lines, embedding \n throughout a single string quickly becomes hard to read. Triple quotes — either """ or ''' — let you write the text exactly as it should appear, with real line breaks inside the string itself.

python
print("""Name:  Jordan
Score: 98
Grade: A""")
output
Name:  Jordan
Score: 98
Grade: A
Pro Tip

Triple-quoted strings preserve every whitespace character exactly as written, including leading spaces on each line. Watch your indentation — any spaces before the text inside the triple quotes will appear in the output.

Connecting Forward

The same \n you see here appears throughout Python — in file reading, network responses, and log output. It is not a print()-specific idea. When you later read a file with open() and strip newlines from each line, you are dealing with the same character. Escape sequences are a universal string concept, not a beginner-mode shortcut.

Other String Formatting Methods

f-strings are the recommended approach for new Python code, but you will encounter two older formatting methods when reading existing code or third-party libraries. Knowing how they work prevents confusion when you see them in the wild.

str.format()

The str.format() method, introduced in Python 2.6 via PEP 3101, works by placing empty curly braces {} as placeholders inside a string, then passing the values to fill them in as arguments to .format(). Positional and named placeholders are both supported.

python
name = "Jordan"
score = 98

# Positional placeholders — filled in order
print("Name: {}, Score: {}".format(name, score))

# Named placeholders — order does not matter
print("Score: {s}, Name: {n}".format(n=name, s=score))

# Format spec works the same way as in f-strings
price = 49.99
print("Total: ${:.2f}".format(price))
output
Name: Jordan, Score: 98
Score: 98, Name: Jordan
Total: $49.99

The % Operator (Legacy)

Python's original string formatting method uses the % operator, inherited from C's printf and available since Python 1. You write format codes like %s (string) and %d (integer) inside a string, then provide the values after the % operator. You will encounter it in older code and tutorials.

python
name = "Jordan"
score = 98

# % formatting — two formats codes, two values in a tuple
print("Name: %s, Score: %d" % (name, score))

# Float with two decimal places
price = 49.99
print("Total: $%.2f" % price)
output
Name: Jordan, Score: 98
Total: $49.99
Why Three Methods Exist

The % operator has been in Python since version 1. str.format() was introduced in Python 2.6 (PEP 3101) to address its limitations — primarily that % only supports a fixed set of types and has a well-known bug when formatting a single tuple. f-strings arrived in Python 3.6 (PEP 498) as the cleanest and fastest option. For new code written on Python 3.6+, f-strings are the correct default. The older methods remain because they are present in decades of existing code you will eventually read.

When using the + operator to build output strings, Python requires every value to already be a string. Passing an integer directly raises a TypeError. This is one of the first errors beginners encounter, and understanding why it happens makes it easy to fix.

python
age = 29

# This raises a TypeError — cannot concatenate str and int
print("Age: " + age)

# Fix 1: wrap the integer with str()
print("Age: " + str(age))

# Fix 2 (preferred): use an f-string instead
print(f"Age: {age}")
output
TypeError: can only concatenate str (not "int") to str
Age: 29
Age: 29
Common Mistake

The TypeError above does not occur with print(age) alone, because print() handles the conversion internally. The error only appears when you try to concatenate a non-string value using + before passing it to print().

spot the bug click the line that contains the bug

The code below should print "Score: 98" but crashes instead. Click the line with the bug, then hit check.

1 score = 98
2 print("Score: " + score)
3 print("Done")
The fix: Change print("Score: " + score) to print("Score: " + str(score)) or use print(f"Score: {score}"). The + operator cannot join a string and an integer directly — Python requires both sides to be the same type.
predict the output read the code, then guess what prints

What does this code print? Think through each line before selecting.

python
name = "Sam"
score = 42
print(f"Player: {name}, Score: {score * 2}")
Why C: f-string curly braces accept any valid Python expression — not just variable names. {score * 2} evaluates the arithmetic first, producing 84, then inserts the result. The expressions inside {} are fully evaluated before the string is built. This is string interpolation at work: Python replaces placeholders with computed values at runtime.

Concatenating strings and variables with the + operator works but gets cluttered quickly. f-strings, introduced in Python 3.6, give you a cleaner syntax. Prefix a string literal with the letter f and place any variable name or expression inside curly braces. Python evaluates what is inside the braces and inserts the result into the string.

PEP 498, which introduced f-strings to Python 3.6, describes them as providing a concise, readable way to include the value of Python expressions inside strings — a design intent that also yields measurable performance improvements over older formatting methods. (Source: PEP 498, Python Software Foundation)

python
name = "Jordan"
score = 98

# Using + concatenation (works but messy)
print("Name: " + name + ", Score: " + str(score))

# Using an f-string (clean and readable)
print(f"Name: {name}, Score: {score}")
output
Name: Jordan, Score: 98
Name: Jordan, Score: 98

Expressions Inside f-Strings

The curly braces in an f-string accept any valid Python expression, not just variable names. You can perform arithmetic, call functions, or use conditional expressions directly inside the braces.

python
price = 49.99
quantity = 3

print(f"Total: ${price * quantity:.2f}")
print(f"Item count: {quantity}")
print(f"{'In stock' if quantity > 0 else 'Out of stock'}")
output
Total: $149.97
Item count: 3
In stock
Note

The :.2f inside the f-string curly braces is a format specification. It tells Python to display the number as a float with exactly two decimal places. Format specifications always follow a colon after the expression.

What's Actually Happening

f-string expressions are evaluated eagerly — at the moment the string is created, not later. When Python encounters f"Total: ${price * quantity:.2f}", it evaluates price * quantity immediately, applies the :.2f format, and embeds the result. There is no deferred evaluation. This matters when you use f-strings inside loops: each iteration captures the current value of variables at that moment, not their future values.

The = Specifier: Built-In Debugging (Python 3.8+)

Python 3.8 added a debugging shortcut inside f-strings that most tutorials skip entirely. Place an equals sign after any expression inside the braces and Python will print both the expression text and its value:

python
price = 49.99
quantity = 3
print(f"{price=}")
print(f"{quantity=}")
print(f"{price * quantity=}")
output
price=49.99
quantity=3
price * quantity=149.97

This works on any valid expression — not just variable names. The output shows the expression as written in your source code alongside the evaluated value. It is the fastest way to inspect variables during development without reaching for a debugger. (Source: Python 3.8 Release Notes, Python Software Foundation)

Connecting Forward

f-string expressions can hold any valid Python expression — including function calls, list comprehensions, and method calls. You will use this constantly once you reach collections and loops. For now, arithmetic and variable names are the main use case. The pattern of {expression} inside a string is the same one you will encounter in template engines, logging formatters, and web frameworks.

How Python evaluates an f-string — static text is kept as-is while expressions inside curly braces are evaluated and replaced.

Under the Hood: stdout and the Type System

Two deeper ideas explain nearly every quirk a beginner encounters with print(). Neither requires advanced knowledge — they are simply the "why" behind behaviors the tutorial has already shown.

Why print() Goes to the Terminal

Every process that runs on an operating system is given three standard streams: stdin (standard input, where keyboard input arrives), stdout (standard output, where normal output goes), and stderr (standard error, where error messages go). print() writes to stdout by default. This is why you can redirect output in the shell with python script.py > output.txt — you are redirecting stdout to a file, and print() follows automatically. print() also has a file keyword argument that lets you send output anywhere a file-like object can receive it.

python
import sys

# Both print the same text — print() uses stdout by default
print("Sent to stdout")
print("Also stdout", file=sys.stdout)

# This sends to stderr instead (used for error/diagnostic messages)
print("This is an error message", file=sys.stderr)
Note

You will see stderr referenced often in Python error tracebacks and logging documentation. Now you know what it refers to: a separate output channel reserved for diagnostic information, kept distinct from normal program output so tools can treat them differently.

Why Python Does Not Coerce Types in Expressions

Python is a strongly typed language. This means it does not silently convert values from one type to another in expressions — you must convert explicitly. When you write "Score: " + 98, Python does not guess that you want 98 as a string. It raises a TypeError instead. This design is intentional: silent type coercion in other languages produces bugs that are very difficult to find because the program continues running with corrupted data. Python's refusal to guess is a feature, not a limitation.

print() appears to contradict this because it accepts integers directly. It does not — internally, print() calls str() on every argument before displaying it. The conversion is explicit, just hidden inside the function. The + operator has no such conversion rule, which is why the two behaviors feel inconsistent to beginners.

How print() processes arguments: each value is converted to a string via str(), joined with the sep character, and the result plus end is written to stdout.
predict the output read the code, then guess what prints

Apply what you know about how print() processes its arguments. What does this code print?

python
print(True, 0, 3.5, sep=" | ")
Why B: print() calls str() on each argument internally — True becomes "True", 0 becomes "0", 3.5 becomes "3.5". No TypeError occurs because print() handles the conversion explicitly before joining. The sep " | " is placed between each converted string, producing True | 0 | 3.5. Option D shows the right values but with added quotes that do not appear in terminal output.

Common Problems and How to Solve Them

These are the problems that actually stop beginners — not the obvious syntax errors, but the ones where the code runs without crashing and still produces the wrong result, or where the right behavior requires knowing something that no introductory paragraph tells you.

Why it happens
When stdout is connected to an interactive terminal, Python flushes the buffer after every newline — output appears immediately. When you redirect to a file (python script.py > out.txt), Python switches to full buffering: it holds output in memory and writes it in large chunks. If a script crashes or finishes before the buffer is flushed, some output may never reach the file, and the order of what does appear can look wrong.
The solution
Pass flush=True to any print() call that must reach the destination immediately: print("Step complete", flush=True). Alternatively, run Python with the -u flag (python -u script.py > out.txt), which forces unbuffered stdout for the entire process. The -u approach is useful in long-running scripts where you want real-time visibility into a redirected log file without modifying every print() call.
Why it happens
When print() calls str() on an argument, Python looks for a __str__ method on the object. If none exists, it falls back to __repr__. If neither is defined on the class, Python uses the default inherited from object, which produces something like <MyClass object at 0x7f3c...> — a type name and memory address that tells you nothing about the object's state.
The solution
Define __str__ on your class to control what print() displays. Define __repr__ to control what appears in the interactive REPL and in debugging contexts. A common pattern is to make __repr__ return a string that could reconstruct the object, and __str__ return a clean, readable description. If you only define one, define __repr__ — when __str__ is not defined, Python falls back to __repr__, but the reverse is not true: a missing __repr__ does not fall back to __str__.
Example
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return f"Point({self.x}, {self.y})"

p = Point(3, 7)
print(p)  # Point(3, 7)
Why it happens
Python preserves every character inside a triple-quoted string exactly as written, including the leading whitespace that makes the code look tidy inside an indented block. When you print that string, those spaces appear as visual indentation in the output — which is rarely what you intended.
The solution
Use textwrap.dedent() from the standard library. It measures the common leading whitespace across all non-empty lines and strips it uniformly. This lets you keep the visual indentation in source while producing clean output at runtime. Import it once at the top of the file: from textwrap import dedent. The alternative — aligning the triple-quoted string against the left margin of the file — works but creates a visual inconsistency in the source that many style guides discourage.
Example
from textwrap import dedent

def show_help():
    print(dedent("""
        Usage: run the script with a filename
        Options:
          --verbose   show detailed output
          --help      show this message
    """).strip())
Why it happens
Using end="" suppresses the newline and keeps output on one line, but stdout may still hold the characters in its internal buffer until it has enough data to write efficiently. The result: a loop printing individual dots finishes the loop first, then flushes everything at once — you see the complete output instantly instead of incrementally.
The solution
Add flush=True alongside end="". The combination forces each character out of the buffer as it is printed: print(".", end="", flush=True). This is the standard pattern for lightweight terminal progress indicators in Python scripts without importing any external library. Note that flush=True has a performance cost when called in a tight loop — it is appropriate for human-visible feedback, not for high-frequency logging.
Why it matters
Beginners are often told "always use f-strings," which is reasonable for display output but is not the right choice in every context. Using the wrong method for the situation produces code that works but is harder to maintain, test, or reuse.
When to use f-strings
f-strings are the right default for output where the template and the data are defined in the same place. They are concise, readable, and fast. They are the correct choice for the majority of print() calls.
When to use str.format()
str.format() is appropriate when the template is defined separately from the values — for example, a message template stored in a configuration file, a database, or a dictionary of translatable strings. f-strings require the variable to be in scope at the point the string is written; str.format() lets you defer that binding. It is also the better choice when you need to reuse the same template with different data across multiple calls.
When to use concatenation
String concatenation with + is appropriate in performance-sensitive loops where you are building strings from other strings and all types are already known to be str. Even then, joining a list with "".join(parts) is faster than repeated + operations because each + creates a new string object in memory.

How to Use print() to Get Output in Python

By this point you have seen every tool individually. Here is how they fit together as a decision sequence — the mental model an experienced Python programmer uses when writing output code, distilled into four questions to ask yourself each time.

  1. Call print() with a string

    Type print() and place your text inside the parentheses surrounded by either single or double quotes. Save your file and run it. The text appears immediately in the terminal. This is the foundation of every output operation in Python.

    What is less obvious at this stage is what is happening at the interpreter level. print() is not writing characters one at a time. It calls sys.stdout.write() internally and flushes the buffer based on whether stdout is attached to an interactive terminal or a pipe. When you run a script normally, stdout is line-buffered — output appears after each newline. When you redirect to a file (python script.py > out.txt), it becomes fully buffered, and you may need flush=True to force output through immediately. This distinction does not matter for simple beginner programs, but understanding it prevents confusion when output appears out of order in automated pipelines.

  2. Print a variable value

    Create a variable and pass it to print() without quotes. Python converts the value to a string representation and displays it. To mix static text and a variable in a single readable call, use an f-string: prefix the opening quote with f and place the variable name inside curly braces.

    The deeper mechanism is __str__ versus __repr__. When print() converts an object, it calls the object's __str__ method — the human-readable representation. If __str__ is not defined, Python falls back to __repr__. This distinction matters when you start building your own classes: print(my_object) will display whatever __str__ returns. Custom objects that do not define __str__ will print something like <MyClass object at 0x7f...> — functional but not helpful. Defining __str__ on your classes makes print() output meaningful from day one.

  3. Control spacing and line endings

    Use the sep keyword argument to replace the default space between multiple values. Use the end keyword argument to replace the default newline that follows each call. Setting end="" lets consecutive print() calls build up a single line of output together.

    A non-obvious use case for end is progress indicators. In terminal scripts, print(".", end="", flush=True) inside a loop produces a growing row of dots on one line — a lightweight progress display that does not require any external library. The flush=True argument is critical here: without it, buffered stdout may hold the dots until the loop ends, defeating the purpose. The combination of end="" and flush=True is a standard pattern for real-time terminal feedback in Python scripts. Similarly, sep is commonly paired with *iterable unpacking: print(*my_list, sep="\n") prints each element of a list on its own line without writing an explicit loop — a concise idiom you will encounter in production code.

  4. Handle special characters and multi-line output

    Use escape sequences like \n (newline) and \t (tab) inside string literals to control layout within a single print() call. For multi-line blocks of text, triple-quoted strings (""") let you write the output across real lines without embedding \n manually. When concatenating strings with +, convert any non-string values with str() first to avoid a TypeError.

    One problem beginners encounter is indentation bleeding into triple-quoted strings. When the string is indented to match surrounding code, those leading spaces become part of the string content and appear in the output. The standard solution is textwrap.dedent() from the standard library, which strips common leading whitespace from all lines. Another option is to align the triple-quoted string against the left margin, accepting the visual inconsistency inside the source file. Understanding this trade-off — readable source code versus clean output — is a practical judgment call that comes up every time you write multi-line terminal messages, help text, or log output.

    For the TypeError, the deeper solution is not just to remember to call str(). It is to choose the right tool for the job. String concatenation with + is appropriate when you are building strings from other strings in a performance-sensitive loop and already control all types. f-strings are better for display output because they handle conversion internally and keep the intent readable. str.format() is worth knowing for templates that are defined separately from their data — for example, message templates loaded from configuration. Each method has a context where it is the cleaner choice; no single one is always correct.

Python Output Summary Points

  1. print() is a built-in function that sends values to stdout — the standard output stream — which appears as your terminal by default. No import is needed.
  2. String literals passed to print() must be wrapped in single or double quotes. Variable names are passed without quotes. print() calls str() internally on every argument, which is why it can display integers and floats without raising a TypeError.
  3. Multiple values separated by commas inside print() are joined with a space by default. sep is a keyword argument that replaces that space with any string you choose.
  4. Each print() call appends a newline by default. end is a keyword argument that replaces the newline with any other string, including an empty string.
  5. Escape sequences like \n (newline) and \t (tab) can appear anywhere inside a string to control layout. They are not print()-specific — the same sequences appear in file I/O, network output, and log messages. Triple-quoted strings (""") preserve real line breaks without any escape sequences.
  6. f-strings (prefix f before the opening quote) are Python's string interpolation feature. Expressions inside curly braces are evaluated eagerly — at the moment the string is created — and the results are embedded in place. Any valid Python expression works inside the braces.
  7. The :.2f syntax after a colon inside f-string braces is a format specification. It controls how the evaluated value is rendered as text (decimal places, padding, alignment).
  8. str.format() is an older interpolation method you will encounter in existing code. Curly-brace placeholders are filled in by values passed to .format(). f-strings are preferred for new code — they are more readable and faster, because they are compiled into optimized bytecode at parse time rather than invoking a method call at runtime.
  9. Python is strongly typed: it does not silently convert values in expressions. The + operator requires both sides to be the same type. Passing an integer without converting it first with str() raises a TypeError. f-strings and print() handle this conversion internally.
  10. print() has a file keyword argument that accepts any file-like object. This lets you redirect output to sys.stderr for error messages, or to an open file handle. The three standard streams — stdin, stdout, stderr — are a universal operating system concept, not Python-specific.

With these tools and the mental model behind them, you can produce any output a beginner program requires. The concepts that appear here — keyword arguments, type conversion, standard streams, string interpolation — are not beginner scaffolding. They are the real mechanisms Python uses at every level of complexity.

check your understanding question 1 of 5

Sources and Further Reading

Every technical claim in this tutorial is traceable to official Python documentation or the PEPs that introduced each feature. The sources below are listed in the order topics appear in the article.

  • Python Software Foundation. Built-in Functions — print(). Python 3 Documentation. docs.python.org/3/library/functions.html#print — The complete, authoritative signature and parameter descriptions for print(), including flush (added in Python 3.3) and file.
  • Smith, Eric V. PEP 498 — Literal String Interpolation. Python Software Foundation, 2015. peps.python.org/pep-0498/ — The proposal that introduced f-strings in Python 3.6. Documents design decisions, expression evaluation rules, and comparisons to prior formatting methods including PEP 215.
  • Talin. PEP 3101 — Advanced String Formatting. Python Software Foundation, 2008. peps.python.org/pep-3101/ — The proposal that introduced str.format() in Python 2.6. Explains the motivation for replacing %-formatting.
  • Python Software Foundation. What's New In Python 3.8 — f-strings: = for quick debugging. Python 3 Documentation. docs.python.org/3/whatsnew/3.8.html — Documents the = specifier added to f-strings in Python 3.8 for inline debugging output.
  • Python Software Foundation. textwrap — Text Wrapping and Filling. Python 3 Standard Library Documentation. docs.python.org/3/library/textwrap.html — Reference for textwrap.dedent(), which strips common leading whitespace from triple-quoted strings.
  • Python Software Foundation. sys — System-specific parameters and functions. Python 3 Standard Library Documentation. docs.python.org/3/library/sys.html#sys.stdout — Documents sys.stdout, sys.stderr, and sys.stdin, including buffering behavior and the effect of the -u flag.

Frequently Asked Questions

print() is Python's built-in function for producing output. It sends text or data to the terminal by default. You call it by typing print() and passing one or more values inside the parentheses.

Pass multiple values to print() separated by commas. By default, Python inserts a single space between each value. You can change this separator with the sep parameter.

sep controls what character or string is placed between each value passed to print(). The default is a single space. Setting sep='' removes spacing; sep='-' inserts a hyphen between values.

end controls what is printed at the very end of the output. The default is a newline character, which is why each print() call starts on a new line. Setting end='' keeps the cursor on the same line.

An f-string is a formatted string literal introduced in Python 3.6. You prefix a string with f or F and place variable names or expressions inside curly braces {}. Python evaluates the expressions and inserts their values into the string at runtime.

Use an f-string: f'The value is {variable}'. This embeds the variable directly in the string. You can also concatenate with the + operator or use str.format(), though f-strings are the readable option for beginners.

Yes. print() accepts integers, floats, and other data types. Python converts them to their string representations automatically before displaying them.

Set end='' in the print() call. This replaces the default newline with an empty string, so the next print() call continues on the same line.

Escape sequences are two-character combinations starting with a backslash that represent special characters inside a string. The two beginners encounter first are \n, which inserts a newline, and \t, which inserts a tab. They can appear anywhere inside a string passed to print() and control the layout of your output without requiring separate print() calls.

Two approaches work well. You can embed \n newline escape sequences directly inside a regular string: print("Line one\nLine two"). Alternatively, use a triple-quoted string, which preserves real line breaks written directly in your code: print("""Line one\nLine two"""). Triple quotes are easier to read when the output spans several lines.

Both methods embed values into strings, but f-strings (introduced in Python 3.6) are more concise. With str.format(), you write placeholders as {} in the string and pass values as arguments to .format(): "Name: {}".format(name). With an f-string, the variable goes directly inside the braces with no separate call: f"Name: {name}". f-strings are also slightly faster and are the recommended style for new code.

The + operator in Python requires both sides to be the same type. When you write "Score: " + 98, you are trying to join a string and an integer, which Python does not allow. Fix it by converting the number first: "Score: " + str(98). The easier solution is to use an f-string instead — f"Score: {98}" — because f-strings handle the type conversion internally.

stdout stands for standard output — one of three streams every process is given by the operating system. The other two are stdin (standard input) and stderr (standard error). print() writes to stdout by default, which is why output appears in your terminal. You can redirect stdout to a file using the shell: python script.py > output.txt. print() also has a file keyword argument that lets you send output to sys.stderr or any file-like object directly from Python code.

Keyword arguments are arguments passed to a function by name rather than by position. When you write print("a", "b", sep="-"), sep="-" is a keyword argument — Python matches it to the sep parameter by name, not by where it appears in the call. This allows sep and end to have default values that you only need to specify when you want to override them. The same pattern appears throughout Python in virtually every function that has optional parameters, making it one of the most important syntactic patterns to recognize early.

String concatenation builds a new string by joining pieces with the + operator: "Hello, " + name. It requires all pieces to already be strings, which is why non-string values must be converted with str() first. String interpolation embeds expressions directly inside a string template using special syntax — in Python, f-strings: f"Hello, {name}". Interpolation handles type conversion internally, is more readable when mixing text and variables, and evaluates expressions at the point the string is created. f-strings are Python's string interpolation feature; the concept exists in many languages under different names.

Added in Python 3.8, the = specifier inside an f-string prints both the expression text and its evaluated value in a single call. Write f"{variable=}" and Python outputs variable=value — the name as written in your source code, an equals sign, and the result. For example, print(f"{quantity=}") where quantity is 3 prints quantity=3. It works on any valid expression: f"{price * quantity=}" prints price * quantity=149.97. This is the fastest way to inspect a value during development without adding a separate label string or opening a debugger.

The % operator is Python's original string formatting method, inherited from C's printf and present since Python 1. It uses format codes like %s for strings and %d for integers: "Name: %s" % name. You do not need to use it for new code — f-strings are the correct default on Python 3.6 and later. You do need to recognize it when reading older tutorials, open source libraries, and codebases written before Python 3.6. Understanding what it does prevents confusion when you encounter it in the wild.

The % operator has been in Python since the beginning. str.format() was introduced in Python 2.6. f-strings require Python 3.6 or later — they will not work on Python 2 or Python 3.5 and earlier. The = debug specifier inside f-strings requires Python 3.8 or later. The flush parameter in print() was added in Python 3.3. If you are starting fresh today, install Python 3.11 or later and you have access to all features covered in this tutorial.

Certificate of Completion
Final Exam
Pass mark: 80% · Score 80% or higher to receive your certificate

Enter your name as you want it to appear on your certificate, then start the exam. Your name is used only to generate your certificate and is never transmitted or stored anywhere.

Question 1 of 10