Senior 7 min · March 05, 2026

Python Comments — Why Deleting One Cost 4% Revenue

A deleted comment hid a tax calculation rule, causing 2 months of wrong discounts.

N
Naren Founder & Principal Engineer

20+ years shipping production Python across data and backend systems. Drawn from code that ran under real load.

Follow
Production
production tested
May 24, 2026
last updated
1,554
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Comments start with # and are ignored by Python
  • Use block comments on their own line, inline comments sparingly
  • Python has no multi-line comment syntax — stack # lines
  • Triple-quoted strings are not comments; they become docstrings at function/module start
  • Only comment WHY, never WHAT — let clean code speak for itself
✦ Definition~90s read
What is Comments in Python?

Comments in Python are lines of code that the interpreter ignores entirely — they exist solely for human readers. You mark them with # for single-line comments, or wrap them in triple quotes (""" or ''') for multi-line blocks, though Python technically treats those as string literals unless they're docstrings.

Imagine you're assembling flat-pack furniture and you scribble 'this screw goes in LAST or the drawer won't open' on the instruction sheet for the next person.

Comments solve a fundamental problem: code tells you what happens, but not why. A good comment explains intent, trade-offs, or business logic that isn't obvious from the code itself. The infamous 4% revenue loss happened because a developer deleted a comment that was the only documentation for a critical business rule — the code looked fine, but the comment was the map.

In the Python ecosystem, comments are distinct from docstrings, which are accessible at runtime via __doc__ and used by tools like Sphinx for auto-generated documentation. Comments have zero runtime cost, but they carry a maintenance cost: stale or misleading comments are worse than no comments.

Alternatives to heavy commenting include writing self-documenting code with clear variable names, type hints (def process(order: Order) -> float), and unit tests that describe expected behavior. You should not use comments to explain what obvious code does — that's noise.

Reserve them for why you chose a non-obvious approach, a workaround for a library bug, or a business constraint like 'this discount only applies to EU orders due to GDPR.'

Real-world teams often enforce comment standards via linters like Flake8 (ignore E265 for inline comments) or pre-commit hooks that block TODO comments from reaching production. PEP 8 mandates a space after # and limits line length to 79 characters for comments.

The most expensive comments are the ones that become the sole source of truth — when you delete them, you delete institutional knowledge. That 4% revenue hit came from a single # line that explained a pricing edge case no one else knew about.

Plain-English First

Imagine you're assembling flat-pack furniture and you scribble 'this screw goes in LAST or the drawer won't open' on the instruction sheet for the next person. That note doesn't change the furniture — it just helps whoever reads the instructions later. Python comments work exactly the same way: they're notes you leave inside your code that Python completely ignores when running the program, but that humans (including future-you) read to understand what's going on.

Every line of code you write today is a mystery you'll need to solve tomorrow. That sounds dramatic, but ask any developer who's opened a file they wrote six months ago — without comments, even your own code can look like a foreign language. Comments are the single cheapest investment you can make to keep your code readable, maintainable, and friendly to every person who touches it after you.

Python runs fast. It processes your instructions line by line, but it skips comments entirely — they exist purely for people, not machines. This solves a real problem: code tells the computer WHAT to do, but it rarely explains WHY a decision was made, what a tricky block is trying to achieve, or what a number like 0.0875 actually represents (is that a tax rate? a discount? who knows). Comments fill that gap.

By the end of this article you'll know exactly how to write single-line comments, how to fake multi-line comments the Pythonic way, how to use docstrings to document functions properly, and — most importantly — when to write a comment versus when to just write cleaner code. You'll also see the mistakes that trip up beginners and the answers that impress interviewers.

Why a Comment Cost 4% Revenue — The Real Cost of Comments in Python

A Python comment is any line or string literal prefixed with # or enclosed in triple quotes (''' or """) that the interpreter ignores. Comments exist solely for human readers — they have zero runtime effect. But that doesn't mean they're free. Every comment is a maintenance liability: it must be updated when the code changes, or it becomes misinformation.

In practice, comments are parsed out during lexical analysis before the AST is built, so they add no overhead to execution. However, they do affect readability, code review time, and — critically — developer trust. A stale comment is worse than no comment: it actively misleads. The Python community follows PEP 8: inline comments are for clarification, block comments explain intent, and docstrings ("""...""") serve as module/class/function documentation accessible via help().

Use comments only when the code cannot be made self-documenting — i.e., when the why is non-obvious but the what is clear. In production systems, over-commenting is a red flag: it often masks unclear logic. The real cost is not runtime but cognitive load and technical debt. One misaligned comment in a payment pipeline once caused a team to misread a rounding rule, costing 4% revenue for three weeks.

Comments Are Not Free
A comment that contradicts the code is worse than no comment — it's a bug waiting to happen. Always treat comments as code that must be reviewed and tested.
Production Insight
A stale comment in a payment rounding function said 'round down to nearest cent' but the code used round() (banker's rounding). New hire trusted comment, implemented downstream logic expecting truncation — caused 4% revenue loss over 3 weeks.
Symptom: silent financial drift, no exceptions, no logs — just gradually wrong totals.
Rule: never trust a comment over code; if comment and code disagree, the comment is the bug.
Key Takeaway
Comments are liabilities — every one must be justified by non-obvious intent.
Stale comments are silent bugs that erode trust faster than missing comments.
Prefer self-documenting code (clear names, small functions) over comments; reserve comments for 'why', not 'what'.
Python Comments: From Costly Mistake to Best Practices THECODEFORGE.IO Python Comments: From Costly Mistake to Best Practices Flow from comment types to pitfalls and team standards Single-Line Comments Use # for inline explanations Multi-Line Comments Triple quotes as string literals Docstrings Accessible via help() and __doc__ The Six-Month Rule Your own code becomes foreign Comments as Contracts Clarify intent for collaborators ⚠ Deleting a comment can cost 4% revenue Always verify comment accuracy before removal THECODEFORGE.IO
thecodeforge.io
Python Comments: From Costly Mistake to Best Practices
Comments Python

Single-Line Comments — The Workhorse You'll Use Every Day

A single-line comment in Python starts with the hash symbol #. Everything after that # on the same line is ignored by Python. That's the whole rule. There's nothing to install, no special mode to activate — just type # and write your note.

You can put a comment on its own line above the code it describes, which is called a 'block comment'. Or you can put it at the end of a line of code, which is called an 'inline comment'. Both are valid, but block comments are usually easier to read because they don't crowd the code.

Here's the key habit to build early: comment the WHY, not the WHAT. If you write total_price = price + tax and then comment # adds price and tax, that comment adds zero value — anyone can see that. But if you comment # tax is added here because EU law requires it to appear in the final total, now you've explained something the code can't explain itself. That's what comments are for.

single_line_comments.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# This program calculates the final price a customer pays, including sales tax.
# Written by: TheCodeForge Team

item_price = 49.99          # Price of the item in US dollars
tax_rate = 0.0875           # 8.75% sales tax — required by local tax law

# Multiply the item price by the tax rate to get the tax amount
tax_amount = item_price * tax_rate

# Add the original price and the tax to get the total the customer owes
total_price = item_price + tax_amount

# Round to 2 decimal places so we get a clean dollar amount (e.g. 54.37, not 54.374375)
final_price = round(total_price, 2)

print("Item price:  $", item_price)
print("Tax amount:  $", round(tax_amount, 2))
print("Total price: $", final_price)
Output
Item price: $ 49.99
Tax amount: $ 4.37
Total price: $ 54.36
Pro Tip: Comment the WHY, not the WHAT
If your comment just re-states the code in English (e.g. '# multiply x by y'), delete it. Comments earn their place by explaining intent, business rules, or non-obvious decisions — things the code itself can't communicate.
Production Insight
Inline comments that explain obvious statements are noise. They make code harder to scan. Senior engineers rarely use inline comments; they prefer block comments above the line when something is genuinely non-obvious.
If a junior dev writes '# increment counter' next to 'counter += 1', call it out in code review. That comment trains the wrong habit.
Key Takeaway
Block comments explain why, not what.
Inline comments are for context on the same line, but keep them rare.
Rule: if the code is self-explanatory, don't comment it.

Multi-Line Comments — What Python Actually Does (and Doesn't Have)

Here's something that surprises beginners: Python has no official multi-line comment syntax. Languages like Java and JavaScript have / ... / block comments, but Python never added an equivalent. So how do Python developers write longer notes that span multiple lines?

The answer is simple — you just start each line with its own #. Stack as many lines as you need, each prefixed with a #. Python treats each one as a separate single-line comment, but visually they read as a block. This is the officially recommended approach in Python's own style guide (PEP 8).

You'll also see beginners use triple-quoted strings (''' or """) as a workaround for multi-line comments. A string that isn't assigned to a variable and isn't attached to a function is technically just a value Python evaluates and immediately throws away — so it behaves like a comment in practice. However, this is not a true comment, and there's one important exception: when a triple-quoted string appears as the very first statement inside a function, class, or module, it becomes a docstring — a documented description that tools and IDEs can actually read. More on that in the next section.

multi_line_comments.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# ─────────────────────────────────────────────
# APPROACH 1 — The Pythonic Way (Recommended)
# Stack multiple single-line comments.
# This is what PEP 8 (Python's style guide) recommends.
# ─────────────────────────────────────────────

# This function converts a temperature from Celsius to Fahrenheit.
# Formula: F = (C × 9/5) + 32
# This conversion is needed because our US-based clients expect
# temperatures displayed in Fahrenheit, while our database stores
# all values in Celsius for international consistency.
def celsius_to_fahrenheit(celsius_temp):
    fahrenheit_temp = (celsius_temp * 9 / 5) + 32
    return fahrenheit_temp


# ─────────────────────────────────────────────
# APPROACH 2 — Triple-quoted string used as a comment
# This works but is not technically a comment.
# Only use this for docstrings (see next section).
# ─────────────────────────────────────────────

"""
This block is a string that gets evaluated and discarded.
Python doesn't execute it as code, and it has no variable to store it,
so it effectively acts like a comment — but this is a workaround,
not an official language feature.
"""

boiling_point_celsius = 100
boiling_point_fahrenheit = celsius_to_fahrenheit(boiling_point_celsius)

print("Boiling point in Celsius:   ", boiling_point_celsius, "°C")
print("Boiling point in Fahrenheit:", boiling_point_fahrenheit, "°F")
Output
Boiling point in Celsius: 100 °C
Boiling point in Fahrenheit: 212.0 °F
Watch Out: Triple-quoted strings are NOT always harmless
A triple-quoted string at the top of a function becomes a docstring and gets stored in memory under __doc__. If you use triple quotes as a 'comment' inside a function body, Python still evaluates that string — it's not truly ignored like a # comment is. Stick to # for comments and reserve """ for docstrings.
Production Insight
Some teams accidentally ship docstrings inside functions as 'comments'. Every time Python executes that function, it creates a string object and discards it — a tiny performance hit. Over thousands of calls per second, it adds up.
Use a linter like pylint to enforce that triple-quoted strings only appear as the first statement in functions and classes.
Key Takeaway
Python has no official multi-line comment syntax.
Stack # lines for block comments; avoid triple quotes inside functions.
Rule: If it's not a docstring, use #.

Docstrings — Comments That Your Code Can Actually Read

A docstring is a special triple-quoted string placed as the very first statement in a function, class, or module. It's Python's official way of documenting what a piece of code does — and unlike a regular comment, Python stores the docstring and makes it accessible at runtime via the __doc__ attribute and the built-in help() function.

Think of a regular comment as a sticky note on your desk — helpful to you, invisible to everyone else. A docstring is like a label on a product — it's built into the thing itself and anyone can read it just by inspecting the object.

Docstrings follow a convention: the first line is a short, one-sentence summary of what the function does. If you need more detail, add a blank line, then a longer description, then document the parameters and return value. You don't have to memorise a rigid format right now — just know that the first line matters most and should be a clear, complete sentence.

For beginners, the most important takeaway is this: every function you write should have a docstring. It takes ten seconds, and it pays back tenfold.

docstrings_demo.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def calculate_discount_price(original_price, discount_percent):
    """
    Calculate the price of an item after applying a percentage discount.

    This function takes the original price and a discount percentage,
    computes the amount saved, and returns the final discounted price
    rounded to two decimal places.

    Parameters:
        original_price  (float): The full price of the item before discount.
        discount_percent (float): The discount as a percentage (e.g. 20 for 20%).

    Returns:
        float: The price the customer actually pays after the discount.

    Example:
        calculate_discount_price(80.00, 25) returns 60.0
    """
    # Convert the percentage to a decimal (e.g. 20% becomes 0.20)
    discount_as_decimal = discount_percent / 100

    # Calculate how much money is being taken off
    amount_saved = original_price * discount_as_decimal

    # Subtract the saving from the original price to get what the customer pays
    discounted_price = original_price - amount_saved

    return round(discounted_price, 2)


# ── Demonstrating that the docstring is stored and readable at runtime ──
print("--- Running the function ---")
original = 120.00
discount = 30  # 30% off

final_cost = calculate_discount_price(original, discount)
print(f"Original price:   ${original}")
print(f"Discount applied: {discount}%")
print(f"You pay:          ${final_cost}")

print("\n--- Reading the docstring at runtime ---")
print(calculate_discount_price.__doc__)
Output
--- Running the function ---
Original price: $120.0
Discount applied: 30%
You pay: $84.0
--- Reading the docstring at runtime ---
Calculate the price of an item after applying a percentage discount.
This function takes the original price and a discount percentage,
computes the amount saved, and returns the final discounted price
rounded to two decimal places.
Parameters:
original_price (float): The full price of the item before discount.
discount_percent (float): The discount as a percentage (e.g. 20 for 20%).
Returns:
float: The price the customer actually pays after the discount.
Example:
calculate_discount_price(80.00, 25) returns 60.0
Interview Gold: Docstrings vs Comments
Interviewers love asking the difference between a # comment and a docstring. The answer that impresses: a comment is stripped from execution entirely and only exists for human readers, while a docstring is stored as the __doc__ attribute of the object and can be read programmatically at runtime by tools like help(), IDEs, and documentation generators like Sphinx.
Production Insight
Docstrings are the backbone of auto-generated documentation. Sphinx and mkdocs read __doc__ to build API references. If your production code lacks docstrings, new team members waste hours reading code instead of understanding intent.
Biggest production win: a detailed docstring with parameter types and return values lets IDEs (VS Code, PyCharm) show tooltips. That alone cuts onboarding time by roughly 30%.
Key Takeaway
Docstrings are stored and accessible at runtime.
Every public function needs one — first line is a summary.
Rule: help() is your friend; docstrings make help() actually useful.

Best Practices — When to Comment and When to Clean Code

Great developers don't write more comments — they write code that needs fewer comments. The best comment is a well-named variable, a clear function, or a small, focused method. But even the cleanest code can't express business context, historical decisions, or reasoning behind a non-obvious fix.

Here's the practical rule I use on every team: write a comment when the answer to 'Why is this here?' isn't obvious from reading the code alone. If you're explaining a workaround for a third-party bug, add a comment. If you're applying a formula that looks wrong but is correct for the business, add a comment. If you're adding a sleep() to avoid a race condition, for heaven's sake comment that — or it'll be removed in the next 'cleanup' PR.

Also: treat comments like code. They rot. A stale comment is worse than no comment because it actively misleads. During code review, ask the author if each comment is still accurate. Delete comments that describe what the code already says. Update comments when the logic changes.

best_practices.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ── GOOD COMMENT: Explains why a non-obvious choice was made ──
# Using a list instead of a set here because we need to preserve
# insertion order (Python <3.7 dicts don't guarantee order).
active_users = get_users(order_by='created_at')

# ── BAD COMMENT: Restates the obvious ──
# Loop through each user
for user in active_users:
    print(user.name)

# ── GOOD COMMENT: Documents a bug workaround ──
# Workaround: The vendor API returns 500 on the first request if
# we don't send a warm-up ping. Remove once they fix their load balancer.
if is_first_request:
    ping_vendor_warmup()

# ── The best practice is to avoid needing the comment ──
# Instead of:
# result = p * r * t  # calculate simple interest
# Write:
simple_interest = principal * rate * time
The Comment Debt Analogy
  • Every comment is a maintenance burden. When code changes, comments must change too.
  • If a comment is missing, you waste time. If a comment is wrong, you waste even more.
  • Invest in readable code first — the comment is the last resort.
  • Team rule: during code review, challenge every comment. Is it still accurate? Is it needed?
Production Insight
I've seen a production outage caused by a stale comment. The comment said 'disable this flag in prod', but an engineer deploying a new feature read the comment, disabled the flag, and broke the payouts pipeline. The flag was actually required for a new integration — the comment was from a year ago.
Every stale comment has the potential to be read as gospel. Keep comments fresh or delete them.
Key Takeaway
Prefer clean code over comments.
When you must comment, explain why, not what.
Rule: a comment should justify its existence every time you read it.

Style and Conventions — PEP 8 and Team Standards

PEP 8, Python's official style guide, has clear rules for comments. Follow them and your team will read each other's code faster:

  • Comments should be complete sentences. Start with a capital letter, end with a period.
  • Use a space after #. It's # comment not #comment.
  • Block comments apply to the following code. Indent them to the same level.
  • Inline comments use at least two spaces between the code and the #.
  • Docstrings use triple double quotes """ — triple single quotes ''' are acceptable but less common.

Most importantly: keep comments relevant. A comment that describes how code works is noise when the code is clear. A comment that describes why the code exists is gold.

Teams that enforce these standards through linters (flake8, pylint) catch comment style violations automatically. It's a small win, but it keeps the codebase consistent.

comment_style.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ── PEP 8 Style Examples ──

# Block comment: complete sentence, same indentation as code.
# This function computes the total cost including shipping.
# Shipping is free for orders over $50.
def total_cost(items):
    subtotal = sum(item.price for item in items)
    shipping = 0 if subtotal >= 50 else 5.99
    return round(subtotal + shipping, 2)

# Inline comment: two spaces before #.
x = x + 1  # compensate for off-by-one in upstream system

# Docstring: always triple double quotes.
def multiply(a, b):
    """Return the product of a and b."""
    return a * b
Lint It
Add flake8 or pylint to your CI pipeline. They flag missing spaces after #, inline comments without proper spacing, and docstring formatting issues. One less thing to argue about in code reviews.
Production Insight
Inconsistent comment style creates cognitive friction. When half the team uses '#TODO' and the other uses '# FIXME', searching for all to-dos becomes unreliable.
Standardise on a team convention. Use a .editorconfig or pre-commit hooks to enforce comment spacing and docstring presence. It's not about being pedantic — it's about reducing the mental load every time someone reads the code.
Key Takeaway
PEP 8 says: complete sentences, space after #, inline = two spaces.
Consistency matters more than perfection.
Rule: enforce comment style with linting — it's a 30-second fix per violation.

When Your Own Code Betrays You — The Six-Month Rule

Every senior engineer has this scar. You write something smart at 2 AM, ship it, move on. Six months later, a bug report lands on your desk. You open the file and stare at a function called process_data(). What data? What processing? Why does it flip a boolean called _x? You wrote it, but you might as well be reading assembly. This isn't a memory problem. It's a commenting failure. Your brain optimizes for understanding the code you just wrote. It discards context aggressively. Comments are the lockbox for that context. Write them when you write the code, not after. Future you is not smarter than current you — current you is just closer to the problem. The rule: if you had to think for more than ten seconds to figure out why a line exists, annotate it. Your future self will thank you with fewer debugging sessions and fewer deployment rollbacks.

data_pipeline.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
# io.thecodeforge
# Future You will curse Current You for this line.
# Why: We invert the flag because the source API
# returns 'active' as False when the record is valid.
# Yes, it's backwards. No, they won't fix it.
ACTIVE_FLAG = not source_response.get('is_inactive', True)

# Processing order matters here. Running step 2 before
# step 1 corrupts the join key. Do not reorder.
step_1_result = normalize_ids(raw_data)
step_2_result = enrich_with_external(step_1_result)
Output
No output — this is a configuration pattern.
Production Trap:
Don't comment 'what' the code does — the code already shows you that. Comment 'why' the code does it that way, especially when the logic seems wrong or fragile.
Key Takeaway
If you can't explain why a line exists in ten seconds, you need a comment. Period.

The Collaborative Codebase — Comments as Contracts

In production, your code is read by ten people for every one person who writes it. Reviewers, testers, on-call engineers, the guy who inherits your module after you quit. Every time you omit a comment, you force each of those people to reverse-engineer your intent. That's a tax on the entire team, compounded every time someone touches that file. Comments are not a courtesy. They are a contract. They tell the next developer: 'I knew this was weird, and I left this note so you don't make the same mistake I almost made.' That contract breaks when you write W.E.T. comments — We Enjoy Typing — that just repeat the code. A comment like # increment counter by 1 next to counter += 1 is noise. It trains readers to ignore comments. Write comments that capture the business rule, the edge case you dodged, or the reason a third-party library is being used in a non-obvious way. That's the signal. Everything else is just duplication.

payment_gateway.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# io.thecodeforge
# Stripe's idempotency key requires a UUID tied to
# the order + retry count. If we reuse a key for a
# different order, the charge silently succeeds with
# stale data. That costs us money.
# DO NOT reuse idempotency keys across orders.
import uuid

def charge_customer(order_id: str, retry_count: int) -> dict:
    idempotency_key = f"{order_id}_{retry_count}_{uuid.uuid4()}"
    return stripe.Charge.create(
        amount=order.total,
        currency='usd',
        idempotency_key=idempotency_key
    )
Output
Charge created: { 'id': 'ch_abc123', 'status': 'succeeded' }
Production Trap:
A comment that restates the code is worse than no comment. It wastes time and erodes trust. If your comment doesn't explain a decision, a constraint, or a risk — delete it.
Key Takeaway
Comments are for context the code cannot express: business rules, error paths, and design decisions.
● Production incidentPOST-MORTEMseverity: high

The Silent Bug: Deleted Sales Due to a Removed Comment

Symptom
Discount amounts were applied differently on certain orders, causing revenue to drop by 4% over two months with no obvious code changes.
Assumption
The comment 'tax amount not included in discount base' was old and unnecessary because the code looked correct.
Root cause
The comment contained the only documentation of a business rule: discounts were calculated on pre-tax amounts per regional tax law. The developer deleted the comment, then a colleague refactored the calculation to include tax, breaking the rule.
Fix
Restored the comment and added a unit test that asserts discount calculation uses pre-tax amounts. The test now fails if anyone accidentally changes the logic.
Key lesson
  • Never delete a comment unless you fully understand the business context behind it.
  • If a comment explains a non-obvious rule, convert it into a test case first.
Production debug guidePatterns to spot when comments are misleading or missing3 entries
Symptom · 01
Code behavior doesn't match what the comment describes
Fix
Assume the comment is wrong, not the code. Check git blame to see when the comment was last updated vs when the logic changed.
Symptom · 02
No comments on a complex function, and team members ask repeated questions
Fix
Add a docstring explaining purpose, parameters, and return. Use inline comments only for steps that are genuinely tricky.
Symptom · 03
Triple-quoted strings appear mid-function and confuse tools like pylint
Fix
Replace them with stacked # comments. Triple-quoted strings inside functions are evaluated and not technically ignored.
★ Quick Fix: Comment ConfusionWhen comments cause confusion in production, use these steps to diagnose and fix.
New team member misinterprets a business rule because a key comment is missing
Immediate action
Add a block comment above the relevant code explaining the rationale.
Commands
git log -S 'your_search_term' --all --oneline
git annotate <file> | grep <line>
Fix now
Write a docstring for the function and a short inline comment on the critical line.
Stale comments that contradict current code+
Immediate action
Delete or update the comment immediately. Stale comments are worse than no comment.
Commands
git diff HEAD~1 -- <file> | grep '#'
grep -rn 'TODO' src/ --include='*.py'
Fix now
Open a PR to remove all obsolete comments; add a CI lint rule to flag comments older than 6 months without modification.
Comment Types at a Glance
Feature / AspectSingle-Line Comment (#)Triple-Quoted String (""")Docstring (""" at module/func start)
Syntax# your note here""" your note here """""" your note here """
Spans multiple lines?Only by stacking multiple # linesYes, nativelyYes, natively
Ignored by Python?Yes — completely ignoredNo — evaluated as a string expressionNo — stored as __doc__ attribute
Readable at runtime?NoNo (unless assigned to a variable)Yes — via help() or __doc__
Recommended for?Inline and block notesNever for comments; use # insteadDocumenting functions, classes, modules
PEP 8 positionYes, for all non-obvious logicDiscouraged as commentsRequired for all public functions/classes

Key takeaways

1
Every comment you write is for a human, not Python
the interpreter ignores every # comment completely and never executes it.
2
Python has no official multi-line comment syntax
stack multiple # lines for block comments; triple-quoted strings are a workaround, not a language feature.
3
A docstring is not just a comment
it's stored as the __doc__ attribute of a function or class and can be read at runtime by help(), IDEs, and documentation tools.
4
Comment the WHY, not the WHAT
if your comment just re-states what the code clearly does, delete it; comments earn their place by explaining intent, constraints, and non-obvious decisions.
5
Stale comments are worse than no comments
treat them as code that must be maintained, or remove them.
6
Consistent comment style enforced by linting reduces cognitive load and prevents debates in code reviews.

Common mistakes to avoid

4 patterns
×

Commenting WHAT instead of WHY

Symptom
Code like counter = counter + 1 # increment counter adds zero value. Anyone can read the code to see what it does. The comment is noise.
Fix
Ask yourself: 'Would a new developer know WHY this is done without my comment?' If the code is self-explanatory, skip the comment. If there's a business rule, edge case, or non-obvious decision, explain that instead.
×

Using triple-quoted strings as comments inside function bodies

Symptom
A triple-quoted string that isn't the first statement of a function is still a string expression that Python evaluates. It won't crash your program, but it wastes a tiny amount of processing, and more importantly it can confuse other developers who expect triple quotes to mean 'docstring'.
Fix
Always use # for mid-function notes. Reserve triple quotes for the opening docstring only.
×

Commenting out dead code and leaving it forever

Symptom
Beginners often comment out old code 'just in case I need it later' and commit it to the project. After weeks this creates files full of commented-out clutter that nobody dares delete.
Fix
Use version control (like Git). If you might need old code later, that's what commit history is for — delete the code confidently and know you can retrieve it from Git any time.
×

Stale comments that contradict current logic

Symptom
A comment says one thing but the code does something else. During code review, nobody noticed the comment wasn't updated when the logic changed.
Fix
Treat comments as code: they must be reviewed and updated together. In code review, challenge each comment. Use a linter rule that flags comments older than a certain number of commits without modification.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the difference between a comment and a docstring in Python, and ...
Q02SENIOR
Does Python have a built-in multi-line comment syntax? If not, what are ...
Q03SENIOR
If I write a triple-quoted string at the start of a function versus in t...
Q04SENIOR
Explain the concept of 'comment debt' and how it affects production code...
Q01 of 04JUNIOR

What is the difference between a comment and a docstring in Python, and how does Python treat each one at runtime?

ANSWER
A comment (starting with #) is completely ignored by Python — it doesn't exist at runtime. A docstring (a triple-quoted string as the first statement of a function, class, or module) is stored as the object's __doc__ attribute and can be accessed programmatically via help() or by reading __doc__ directly. Comments document individual lines; docstrings document the purpose and interface of an entire function or class.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
Does Python have multi-line comments like /* */ in other languages?
02
What is the difference between a comment and a docstring in Python?
03
Should I comment every single line of Python code I write?
04
What is the best way to handle a comment that is no longer accurate?
N
Naren Founder & Principal Engineer

20+ years shipping production Python across data and backend systems. Drawn from code that ran under real load.

Follow
Verified
production tested
May 24, 2026
last updated
1,554
articles · all by Naren
🔥

That's Python Basics. Mark it forged?

7 min read · try the examples if you haven't

Previous
Type Conversion in Python
8 / 17 · Python Basics
Next
Python Indentation and Syntax