A comment is a note that Python completely ignores. Put a # anywhere on a line, and everything from there to the end of the line is for humans, not the computer:
print("Hi") # this part is a comment
Comments do not change what a program does — not one bit. Their job is to leave clues for the next person who reads the code, and that person is very often you, six months later, trying to remember why you wrote something the way you did. Good comments are the difference between code you can return to and code you have to re-learn from scratch.
flowchart LR L["print(result)"] --> R["runs"] C["a comment"] --> S["skipped by Python"] style L fill:#3776ab,color:#fff style C fill:#9aa4af,color:#fff
Two places to put a comment
An inline comment sits at the end of a line of code, explaining that one statement. A block comment is several # lines stacked together to introduce a whole section:
# Convert a temperature from Celsius to Fahrenheit.
# Uses the standard formula: F = C * 9/5 + 32
celsius = 25
fahrenheit = celsius * 9 / 5 + 32
print(celsius, "C is", fahrenheit, "F")
Block comments suit a chunk of logic that needs context; inline comments suit a single line that would otherwise raise a question. Use both sparingly — a comment earns its place only when it says something the code cannot.
# Convert Celsius to Fahrenheit celsius = 25 fahrenheit = celsius * 9 / 5 + 32 # the standard formula print(celsius, "C is", fahrenheit, "F")
Explain the why, not the what
The single most important rule: a comment should explain why, not restate what. The code already shows what it does — that is its job. A comment that merely repeats it adds noise:
count = count + 1 # add one to count <- says nothing new
count = count + 1 # retry counter for flaky API <- now we're talking
The second comment is worth keeping because it captures an intent — this counter exists because the API is unreliable — that no reader could recover from count = count + 1 alone. That is the bar: would a future reader understand the code better with this line? If not, delete it.
flowchart LR G["good comment: explains the why"] --> OK["keep it"] Bp["bad comment: restates the code"] --> CUT["delete it"] Cl["clear, well-named code"] --> NONE["no comment needed"] style G fill:#3776ab,color:#fff style Bp fill:#b45309,color:#fff style Cl fill:#3776ab,color:#fff
Comments rescue your future self
The comment that feels obvious today — why this loop starts at 1 instead of 0, why we round down here — is exactly the one you will wish existed when you come back cold, months later, with the original reasoning gone. Code shows what happens; a well-placed comment shows what was in the author's head.
A line of code answers how; a good comment answers why. The best notes capture things the source cannot carry: a hidden assumption, a constraint a user once hit, a pointer to the ticket that introduced the line. If reading the code alone leaves you guessing about the intent, that gap is precisely where a comment belongs.
flowchart TD
Q{"is the code clear?"} -- "no" --> R["rename or rewrite first"]
Q -- "yes" --> Q2{"does it hide a why?"}
Q2 -- "yes" --> C["write a comment"]
Q2 -- "no" --> N["leave it alone"]
style C fill:#3776ab,color:#fff
style N fill:#9aa4af,color:#fff
Good names do the job of comments
Before reaching for a comment, ask whether a better name would make it unnecessary. A function called process(data) hides its purpose and demands a comment; the same code renamed remove_duplicates(rows) states its intent at every call site, for free. Names travel with the code everywhere it is used; a comment stays on one line and is easy to drift out of sync.
That is why experienced developers rename first and comment second. A clear name is a comment you never have to maintain, because it cannot fall out of step with the code it describes.
Docstrings: comments Python can read
Python has a special kind of comment called a docstring — a triple-quoted string placed immediately after a def or class line. Unlike a # comment, a docstring is stored on the object and tools can read it:
def area(width, height):
"""Return the area of a rectangle (width * height)."""
return width * height
Now area.__doc__ holds that string, and editors, help systems, and documentation generators can display it. Use # for short in-file notes to yourself, and use a docstring when you are explaining what a function or class is for — that is the contract other code, and other people, will rely on.
def area(width, height):
"""Return the area of a rectangle (width * height)."""
return width * height
print(area.__doc__)
print(area(3, 4))
Docstring conventions worth knowing
A docstring follows a few habits that make it useful to tools. It sits as the very first statement under the def or class line, wrapped in triple double-quotes. The first line is a short summary that fits on one row, and if you need more, a blank line separates that summary from a longer explanation.
Because the object keeps the docstring, calling help(area) prints it, and editors surface it as a hint wherever the function is used. That turns a quiet note into living documentation that travels with the code — quite different from a # comment, which nothing ever reads back.
# Pricing helpers for the checkout flow.
# Keep all rounding in one place so rates stay consistent.
def final_price(base, tax_rate):
"""Return base price after applying a percentage tax_rate."""
return base + base * tax_rate
print(final_price(100, 0.08))
What does this print? Comments — even a whole commented-out line — are ignored by Python. Predict the exact output.
# This program greets a user
name = "Lin" # set the name
# print("Hello, TEST")
print("Hello,", name)
Anything after # is ignored, including the print on line 3.
Only the last line actually runs.
Which comment best explains the line tax = subtotal * 0.08?
A good comment explains the why — here, that 0.08 is an 8% regional sales tax and where the rate comes from. The arithmetic is already obvious from the code.
Write volume(width, height, depth) that returns the product of its three arguments and carries a docstring as its very first line describing what it returns.
def volume(width, height, depth):
# add a docstring on the line below, then return the product
pass
A docstring is a triple-quoted string placed immediately under the def line.
Return width * height * depth; the docstring is what makes volume.doc truthy.
def volume(width, height, depth):
"""Return the volume of a box (width * height * depth)."""
return width * height * depth
You see the line x = x * 1.8 + 32 buried in a program. Which change makes it clearest for future readers?
A clear name says what the code means with no comment at all. Renaming x and wrapping the math in celsius_to_fahrenheit makes the intent obvious everywhere it is used; a comment restating the arithmetic would only add noise.
Write circle_area(radius) that returns the area of a circle (pi times radius squared, using 3.14159 for pi). Its very first line must be a docstring describing what it returns, and the docstring must contain the word area.
def circle_area(radius):
# docstring first, then return the area
pass
A triple-quoted string sits immediately under the def line.
Return 3.14159 * radius * radius; include the word 'area' somewhere in the docstring.
def circle_area(radius):
"""Return the area of a circle (pi * radius squared)."""
return 3.14159 * radius * radius
Recap
- A
#starts a comment; Python ignores everything after it on that line. - Use inline comments for one line, block comments (several
#lines) for a section. - Aim to explain why a line exists, not what it does — the code already shows the what.
- A docstring (triple-quoted, first line of a
deforclass) documents what something is for, and tools can read it. - When the code is clear, the best comment is none at all — rename a variable instead.
Next you will start organizing many lines of code into functions, where good names and docstrings do most of the explaining for you.