I Stopped Writing Comments and My Python Code Got Better — Here’s Why

Here’s how ditching excessive comments pushed me to write more readable, self-documenting Python — and why you might want to do the same.

I Stopped Writing Comments and My Python Code Got Better — Here’s Why
Photo by Joshua Aragon on Unsplash

I used to think more comments meant better code. Then I realized I was explaining things that clean code shouldn’t need to explain.

I Stopped Writing Comments and My Python Code Got Better — Here’s Why

A few months ago, I did something most developers would call blasphemy:
I stopped writing comments in my Python code.

No # this function calculates the sum, no docstrings that just echo the function name, and certainly no verbose explanations for every other line. It wasn't out of laziness. In fact, it was a deliberate experiment inspired by a conversation with a senior developer who said something that stuck with me:

“If your code needs a comment to be understood, maybe it’s not your code that needs fixing.”

It hit me like a KeyError.


The Illusion of Helpful Comments

We’re taught early in our careers to comment everything. It’s even framed as a “best practice.” But over time, I noticed a pattern: most of the comments I wrote were either:

  • Repeating what the code already said,
  • Getting outdated and misleading,
  • Or cluttering the file with noise.

Take this for example:

# Add 1 to the user's age 
user_age = age + 1

If your variable names are meaningful, that comment is pointless.

Worse, if later the logic changes and the comment isn’t updated, it becomes dangerously misleading.

Writing Clearer Code Instead

Once I stopped relying on comments, I had no choice but to make the code itself do the explaining. That meant:

1. Meaningful Variable and Function Names

def calculate_final_price(cart_items, tax_rate): 
    ...

Instead of this:

def calc(items, tr): 
    ...

I began to treat naming as a critical part of my thought process, not an afterthought.

If I couldn’t name something clearly, it usually meant I hadn’t understood the logic clearly myself.

2. Smaller, Focused Functions

Big functions beg for comments because they do too much.

I broke them down:

def apply_discount(price, discount): 
    return price - (price * discount) 
 
def calculate_tax(price, tax_rate): 
    return price * tax_rate 
 
def calculate_total(cart_items, discount, tax_rate): 
    subtotal = sum(cart_items) 
    discounted = apply_discount(subtotal, discount) 
    tax = calculate_tax(discounted, tax_rate) 
    return discounted + tax

Now, each piece is self-explanatory. I don’t need # calculate tax when the function name does the job.

3. Using Docstrings Where It Matters

I didn’t abandon documentation altogether.

For public APIs, complex logic, or functions with side effects, I still use docstrings — but only when they add true clarity.

def normalize_data(data: list[float]) -> list[float]: 
    """ 
    Scales the list of floats to a 0–1 range. 
    """ 
    ...

Notice the docstring explains why the function exists, not what the code does line-by-line. That’s the key.

The Benefits I Didn’t Expect

This shift did more than declutter my code. It made me a better developer in ways I didn’t expect:

  • I became more intentional with every line I wrote.
  • I spent less time debugging, because there were fewer mismatches between code and comments.
  • Other devs stopped asking for explanations, because the code was genuinely easier to read.

Ironically, the more I wrote for humans in code, the less I needed to write outside of it.

When Comments Do Belong

I’m not saying comments are useless. Here are three places where I still use them — deliberately:

  • Workarounds and Hacks
    If I’m doing something non-obvious due to a bug or external constraint:
# Workaround for issue #123 — API returns wrong format on weekends
  • TODOs or FIXMEs
    For marking future work that shouldn’t be forgotten.
  • Explaining Intent in Complex Logic
    If something is genuinely tricky or domain-specific:
# Negative values here represent refunds, not expenses

But 95% of my previous comments? Gone — and not missed.


Final Thoughts

When you stop treating comments as a crutch, you force yourself to write cleaner, clearer, more intentional code.

That’s the real job of a developer — not just to make things work, but to make them understandable.

So the next time you feel the urge to write a comment, pause.
Ask yourself: Could I write this code so that the comment isn’t needed at all?

Because great code doesn’t explain itself in words — it shows you what it means.


Liked this? Follow me for more honest dev stories, Python insights, and lessons I’ve learned the hard way.

Photo by Sorasak on Unsplash