How to Write Good Python Functions: Six Guidelines for Idiomatic Code
This article outlines six practical guidelines for writing clean, maintainable Python functions—including meaningful naming, single responsibility, comprehensive docstrings, returning useful values, limiting length, and ensuring idempotence or purity—illustrated with code examples and explanations to help developers improve function quality.
Python is powerful but writing good functions can be challenging. This article, based on the Medium post "Writing Idiomatic Python", presents six recommendations to help developers create clean, readable, and testable functions.
What Makes a Good Function?
A function is considered good when it satisfies most of the following criteria:
Reasonable naming
Single responsibility
Includes a docstring
Returns a value
Does not exceed 50 lines
Is idempotent or pure
Naming
Good names should avoid obscure abbreviations and convey the function’s purpose. For example, the poorly named function: def get_knn(from_df): uses the abbreviation knn (K‑Nearest Neighbors) and the vague verb get. A clearer alternative is: def k_nearest_neighbors(dataframe): This name tells a reader exactly what the function does and what type of argument it expects.
Single Responsibility
A function should do only one thing. Combining calculation and printing, as in the following example, violates this principle:
def calculate_and_print_stats(list_of_numbers):
sum = sum(list_of_numbers)
mean = statistics.mean(list_of_numbers)
median = statistics.median(list_of_numbers)
mode = statistics.mode(list_of_numbers)
print('---Stats---')
print('SUM: {}'.format(sum))
print('MEAN: {}'.format(mean))
print('MEDIAN: {}'.format(median))
print('MODE: {}'.format(mode))It is better to split the logic into two functions: one that computes and returns the statistics, and another that formats and prints them.
Docstrings
Every function should have a docstring that follows PEP‑257: a concise one‑sentence summary, proper punctuation, and clear description of parameters and return values. Writing the docstring before the implementation encourages thoughtful design.
Return Values
Functions should always return a useful value. Even if the primary purpose is I/O, returning a status (e.g., True) makes testing easier. When multiple values are needed, return a tuple.
Example of a function without an explicit return (implicitly returns None):
def add(a, b):
print(a + b)Contrast with a proper implementation:
def add(a, b):
return a + bFunction Length
Long functions are hard to understand and maintain. Keeping functions under about 50 lines (often much shorter) improves readability. If a function grows too large, refactor by extracting logical blocks into smaller helper functions.
Idempotence and Purity
An idempotent function returns the same result for the same inputs, regardless of how many times it is called. Example of an idempotent function:
def add_three(number):
"""Return number + 3."""
return number + 3A non‑idempotent version that reads user input each call:
def add_three():
"""Return 3 + the number entered by the user."""
number = int(input('Enter a number: '))
return number + 3Pure functions are a stricter subset: they are idempotent and have no observable side effects (no I/O, no modification of external state). Pure functions are easier to test and reason about.
Why Idempotence and Purity Matter
Both properties simplify testing, refactoring, and reasoning about code. Idempotent functions can be called repeatedly without changing program state, while pure functions guarantee that the only effect of a call is its return value.
In practice, aiming for pure or at least idempotent functions leads to more maintainable and reliable code, even though it may not always be possible to eliminate all side effects.
Overall, being conscious about naming, responsibility, documentation, return values, length, and functional purity helps developers write better Python functions.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
