Fundamentals 5 min read

How to Refactor Flag‑Heavy Python Functions for Cleaner, Scalable Code

This article examines a Python function overloaded with flags, explains why such design harms readability, testability, and extensibility, and demonstrates step‑by‑step refactoring using descriptive helper functions, a pipeline approach, flexible step lists, and type annotations to produce clean, maintainable code.

Code Mala Tang
Code Mala Tang
Code Mala Tang
How to Refactor Flag‑Heavy Python Functions for Cleaner, Scalable Code

How to Optimize

I tried to rewrite the function in a clear and simple way.

1. Use Descriptive Function Names

Instead of using flags for each task, I created separate functions:

<code>def filter_digits(data):
    return [item for item in data if item.isdigit()]


def to_uppercase(data):
    return [item.upper() for item in data]


def sort_data(data):
    return sorted(data)


def format_result(data):
    return "Processed: " + ", ".join(data)
</code>

Now each function does only one thing.

2. Create a Pipeline

Then I connected these functions together in a pipeline‑style flow, which makes the process clearer.

<code>def process_data_pipeline(data):
    data = filter_digits(data)
    data = to_uppercase(data)
    data = sort_data(data)
    return format_result(data)
</code>

3. Make It More Flexible

We can use a list of functions to apply steps dynamically, which is useful when we want to skip certain operations.

<code>def process_data(data, steps):
    for step in steps:
        data = step(data)
    return data

steps = [filter_digits, to_uppercase, sort_data, format_result]
result = process_data(my_data, steps)
</code>

Now we have full control over the steps and can add or remove them without extra flags.

4. Add Type Annotations

I added type hints to make the code easier to read and reduce errors.

<code>from typing import List, Callable

def process_data(data: List[str], steps: List[Callable[[List[str]], List[str]]]) -> str:
    for step in steps:
        data = step(data)
    return data
</code>

Why Change It

Each function should have a single, clear purpose, improving readability.

Separate functions increase reusability; e.g., filter_digits can be used elsewhere.

Testing becomes easier because individual functions are simpler to test.

The design is more extensible; new steps can be added by writing a new function and appending it to the list.

Summary

Next time you write a function, ask yourself: Is it trying to do too many things? Can someone understand the code without a detailed explanation? If the answer is "no," it's time to refactor.

Feel free to share your own experiences.

Pythoncode qualityrefactoringpipelinetype hintssingle responsibility
Code Mala Tang
Written by

Code Mala Tang

Read source code together, write articles together, and enjoy spicy hot pot together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.