Python Comments
A comment is text in your source code that the Python interpreter deliberately ignores. Comments exist purely for humans: they explain why code does what it does, leave notes for your future self, and help teammates understand a codebase without changing how the program behaves. Mastering comments is a small skill with a big payoff — well-commented code is dramatically easier to read, debug, and maintain.
Overview / How it works
Python has exactly one true comment character: #. When the interpreter’s tokenizer scans your source file, anything from a # symbol to the end of that physical line is treated as a comment and stripped out before the code is even parsed into an abstract syntax tree. Comments never become part of the compiled bytecode, so they have zero effect on how your program runs and zero runtime cost.
Python does not have a dedicated syntax for multi-line comments like /* ... */ in C or JavaScript. Instead, Python programmers write consecutive single-line comments, one # per line, to form a comment block. You will also frequently see triple-quoted strings ("""like this""") used to comment out large sections of code or to write long explanatory notes. It is important to understand that a triple-quoted string is not a comment at all — it is a real string literal. When such a string appears as the very first statement inside a module, class, or function, Python treats it specially and stores it as that object’s __doc__ attribute, known as a docstring. Anywhere else, a bare string literal is just an ordinary expression statement: Python evaluates it, creates a string object in memory, and then immediately discards that object since nothing references it.
Comments can appear on their own line, or after code on the same line (an inline comment). The first line of a script sometimes begins with #!/usr/bin/env python3, called a shebang line. To Python this is just another comment, but on Unix-like systems it tells the shell which interpreter to use when the file is executed directly.
Syntax
# Single-line comment: everything after '#' to end of line is ignored
x = 10 # inline comment: explanation follows the code on the same line
# Multi-line comments are written as consecutive
# single-line comments, one per line, each
# starting with its own '#' symbol
"""
A triple-quoted string is not technically a comment,
but is commonly used as a multi-line block comment
or, at the start of a module/function/class, as a docstring.
"""
print(x)
| Form | Example | Notes |
|---|---|---|
| Full-line comment | # explain the next line |
Starts at column 0 or matches surrounding indentation |
| Inline comment | x = 10 # units: seconds |
PEP 8 recommends at least two spaces before # |
| Multi-line comment | several # lines in a row |
The only way to write a "block" comment in Python |
| Docstring | """Explain this function.""" |
Not a comment — a string stored in __doc__ |
| Shebang | #!/usr/bin/env python3 |
A comment to Python, an instruction to the OS shell |
Examples
Example 1: Basic comments in a small calculation
# This program calculates the area of a circle
radius = 5 # radius in centimeters
pi = 3.14159
area = pi * radius ** 2 # A = pi * r^2
print(f"The area of the circle is {area} cm^2")
Output:
The area of the circle is 78.53975 cm^2
Here the standalone comment at the top explains the whole program’s purpose, while the inline comments clarify what an otherwise cryptic variable or formula means. None of these comments change the calculation — delete them and the printed value is identical.
Example 2: Multi-line comments and a triple-quoted string
# This is a multi-line comment
# explaining the purpose of this script.
# It converts a temperature from Celsius to Fahrenheit.
"""
This triple-quoted string is NOT a comment to Python.
It is a string literal. When it appears alone as a statement
it is still just evaluated and thrown away here, since it is
not the first statement in a module, function, or class.
"""
celsius = 25
fahrenheit = celsius * 9 / 5 + 32
print(f"{celsius}C is {fahrenheit}F")
Output:
25C is 77.0F
The three # lines at the top form a multi-line comment block. The triple-quoted string below it is often used the same way in practice, but technically it is a string expression that Python builds and discards; it just happens to have no observable effect here, which is why it feels like a comment.
Example 3: Comments vs. a real docstring in a function
def calculate_discount(price: float, percent: float) -> float:
"""Return price after applying a percent discount (not a comment)."""
# Convert percent (e.g. 20) into a decimal fraction (e.g. 0.20)
discount_fraction = percent / 100
# Uncomment the next line to debug the discount fraction:
# print(f"discount_fraction = {discount_fraction}")
final_price = price - (price * discount_fraction)
return round(final_price, 2)
original_price = 80.0
discounted = calculate_discount(original_price, 25)
print(f"Original: ${original_price}")
print(f"After discount: ${discounted}")
print(calculate_discount.__doc__)
Output:
Original: $80.0
After discount: $60.0
Return price after applying a percent discount (not a comment).
This example shows the key distinction in one place: the # lines inside the function are true comments and vanish completely, while the triple-quoted string right after the def line is a docstring — it is stored on the function object and can be retrieved at runtime through calculate_discount.__doc__ or the built-in help() function. Comments are invisible to your running program; docstrings are actual, inspectable data.
Under the hood
When you run a .py file, CPython’s tokenizer reads the source character by character to produce a stream of tokens (names, numbers, operators, keywords, and so on). As soon as it sees a # that is not inside a string literal, it treats the rest of that physical line as a COMMENT token and moves on — that token is dropped before the parser builds the syntax tree, so comments never reach the compiler and never appear in the compiled bytecode (you can confirm this yourself with the dis module, which will show no trace of any comment). A # that appears inside a string, such as "price #1", is just an ordinary character and is not treated as a comment, because the tokenizer recognizes string boundaries first.
Docstrings work differently because they are not comments at all. The compiler specifically checks whether the first statement inside a module, class, or function body is a bare string literal. If it is, that string is compiled as a normal constant and then bound to the object’s __doc__ attribute automatically. That is why calculate_discount.__doc__ works in Example 3: the docstring genuinely exists at runtime as a string object, unlike the # comments around it, which have already been discarded by the time the function object is created.
Common Mistakes
Mistake 1: The comment describes the code incorrectly
total = 10
# Add 1 to the total
total = total + 5
print(total)
Output:
15
The comment says "Add 1", but the code actually adds 5. This is one of the most common real-world bugs with comments: the code changes over time but the comment is never updated, so it becomes actively misleading — worse than having no comment at all. Always update or delete a comment the moment the code it describes changes:
total = 10
# Add 5 bonus points to the total
total = total + 5
print(total)
Output:
15
Mistake 2: Comments that restate the obvious instead of adding value
x = 42 #this comment is hard to read and provides no value
print(x)
Output:
42
Two problems here: the comment has no space after # (PEP 8 recommends "# " for readability) and, more importantly, it explains nothing useful about x. A good comment explains why a value or decision exists, not just restates what is already obvious from the code itself:
x = 42 # Number of items currently in stock
print(x)
Output:
42
Best Practices
- Write comments that explain why the code does something (a business rule, a workaround, a non-obvious constraint) rather than restating what the code already makes clear.
- Follow PEP 8: use one space after the
#for block comments, and at least two spaces before an inline#. - Keep comments up to date. A stale comment that contradicts the code is more dangerous than no comment at all — treat "update the comment" as part of every code change.
- Use real docstrings (
"""..."""right afterdef,class, or at the top of a module) to document what a function, class, or module does, since docstrings are inspectable viahelp()and tools like Sphinx; reserve#comments for implementation notes inside the body. - Avoid leaving large blocks of commented-out dead code in a codebase long-term; delete it and rely on version control (Git) history if you might need it later.
- Don’t over-comment trivial code. Clear variable and function names (like
total_priceinstead oftp) often remove the need for a comment entirely. - Use short
# TODO:or# FIXME:tagged comments to flag known gaps, since many editors highlight and let you search for these tags.
Practice Exercises
- Write a short script with three variables (
name,age,city) and add a single-line comment above each one explaining its purpose, plus one inline comment on the line that prints them. - Take a function you have written before (or write a simple one, such as computing a rectangle’s perimeter) and add a proper docstring to it. Then write a line of code that prints the function’s
__doc__attribute to confirm it worked. - Given this buggy comment, rewrite the comment so it accurately describes the code:
# subtract the taxabove a line that readsprice = price + tax. What should the corrected comment say, and should the code or the comment change to fix the underlying bug?
Summary
- A comment begins with
#and runs to the end of the physical line; it is discarded by the tokenizer and has no effect on the running program. - Python has no dedicated multi-line comment syntax; use consecutive
#lines to form a block comment. - Triple-quoted strings are not comments — they are string literals, and only the first one inside a module, class, or function becomes that object’s special
__doc__docstring. - PEP 8 recommends one space after
#and at least two spaces before an inline comment. - Good comments explain why, stay in sync with the code, and don’t restate what clear naming already communicates.
