Python Comments — Why Deleting One Cost 4% Revenue
A deleted comment hid a tax calculation rule, causing 2 months of wrong discounts.
20+ years shipping production Python across data and backend systems. Drawn from code that ran under real load.
- 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
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.
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.
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.
round() (banker's rounding). New hire trusted comment, implemented downstream logic expecting truncation — caused 4% revenue loss over 3 weeks.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.
# 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)
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.
# ───────────────────────────────────────────── # 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")
__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.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 function.help()
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.
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__)
# 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.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.
# ── 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
- 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?
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# commentnot#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.
# ── 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
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 . What data? What processing? Why does it flip a boolean called process_data()_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.
# 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)
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.
# 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 )
The Silent Bug: Deleted Sales Due to a Removed Comment
- 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.
git log -S 'your_search_term' --all --onelinegit annotate <file> | grep <line>git diff HEAD~1 -- <file> | grep '#'grep -rn 'TODO' src/ --include='*.py'| Feature / Aspect | Single-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 # lines | Yes, natively | Yes, natively |
| Ignored by Python? | Yes — completely ignored | No — evaluated as a string expression | No — stored as __doc__ attribute |
| Readable at runtime? | No | No (unless assigned to a variable) | Yes — via help() or __doc__ |
| Recommended for? | Inline and block notes | Never for comments; use # instead | Documenting functions, classes, modules |
| PEP 8 position | Yes, for all non-obvious logic | Discouraged as comments | Required for all public functions/classes |
Key takeaways
help(), IDEs, and documentation tools.Common mistakes to avoid
4 patternsCommenting WHAT instead of WHY
counter = counter + 1 # increment counter adds zero value. Anyone can read the code to see what it does. The comment is noise.Using triple-quoted strings as comments inside function bodies
Commenting out dead code and leaving it forever
Stale comments that contradict current logic
Interview Questions on This Topic
What is the difference between a comment and a docstring in Python, and how does Python treat each one at runtime?
__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.Does Python have a built-in multi-line comment syntax? If not, what are the two approaches developers use, and which one does PEP 8 recommend?
If I write a triple-quoted string at the start of a function versus in the middle of a function, does Python treat them the same way? Explain what happens in each case.
help(). A triple-quoted string placed in the middle of a function is just a string expression that Python evaluates (creating a string object) and immediately discards if not assigned or used. It is not stored anywhere and is not a true comment — it's a runtime operation (though tiny) and can confuse developers who expect it to be ignored.Explain the concept of 'comment debt' and how it affects production codebases.
Frequently Asked Questions
No, Python has no dedicated multi-line comment syntax. The standard approach is to prefix each line with a # symbol and stack them vertically. Some developers use triple-quoted strings as a workaround, but these are technically string expressions, not true comments, so the recommended PEP 8 approach is always stacked # lines.
A comment (starting with #) is completely ignored by Python at runtime and exists only for human readers. A docstring (a triple-quoted string as the first statement of a function, class, or module) is stored in memory as the object's __doc__ attribute and can be accessed programmatically using help() or by reading __doc__ directly. Comments document individual lines of logic; docstrings document the purpose and interface of an entire function or class.
No — over-commenting is just as harmful as under-commenting. Well-named variables and functions often make code self-documenting. A comment earns its place when it explains WHY a decision was made, documents a business rule, warns about a non-obvious side effect, or clarifies a complex algorithm. If the comment just re-states what the code obviously does, it's noise — remove it.
Update it immediately, or delete it. A stale comment is more dangerous than no comment because it actively misleads. During code review, challenge every comment that seems outdated. Use git blame to see when the comment was last modified relative to the code it describes.
20+ years shipping production Python across data and backend systems. Drawn from code that ran under real load.
That's Python Basics. Mark it forged?
7 min read · try the examples if you haven't