What is a Pure Function in Python?

When we talk about pure functions in Python, we’re referring to a simple concept: a function that always gives the same output for the same input and doesn’t change anything outside of itself. These functions are core to functional programming and can make your code easier to understand, test, and maintain.
Let’s break down what makes a function “pure.”
Characteristics of a Pure Function
- Same Input, Same Output: A pure function always produces the same result when given the same inputs. There’s no randomness or hidden factors involved.
- No Side Effects: A pure function doesn’t change anything outside of itself. It won’t modify a global variable, write to a file, or print to the console. Its only job is to take inputs, process them, and return a result.
Why Are Pure Functions Useful?
Pure functions might sound like a strict way to code, but they bring some real advantages:
Easier to Test: Because they always return the same output for the same input, you can easily test them without worrying about the system's state.
More Predictable: Since pure functions don’t change anything outside of themselves, they behave in a way that’s predictable and easier to reason about.
Thread-Safe: Pure functions don’t rely on or modify shared variables, making them safe to use in multi-threaded applications.
Example of a Pure Function
Let’s look at a simple example to see how a pure function works in Python. We’ll write a function that calculates the sum of the squares of two numbers:
def sum_of_squares(a, b):
return a**2 + b**2
Why is this a Pure Function?
Same Input, Same Output: Every time you call
sum_of_squares(3, 4)
, it will always return25
. The result doesn’t change based on anything outside the function.No Side Effects: It doesn’t change any variables outside the function. It only calculates a value and returns it.
Testing the Pure Function
print(sum_of_squares(3, 4)) # Output: 25
print(sum_of_squares(5, 6)) # Output: 61
No matter how often you run this, you’ll always get the same result for the same input values.
What is a Non-Pure Function?
Now let’s look at a function that doesn’t follow these rules. Here’s an example of a non-pure function:
result = 0
def add_to_result(a):
global result
result += a
return result
Why is This Non-Pure?
Global State: The function changes the value of the global variable
result
. So the output depends not only on the input but also on the state ofresult
.Side Effects: By changing the global variable
result
, this function affects things outside of itself.
Testing the Non-Pure Function
print(add_to_result(5)) # Output: 5
print(add_to_result(10)) # Output: 15
Notice how the second call add_to_result(10)
is produced 15
because it’s using the updated value result
from the previous call. This makes the function less predictable and harder to test.
Advantages of Using Pure Functions
Easier to Understand: Since pure functions don’t rely on anything outside their scope, they are much easier to read and understand. You don’t have to worry about how they might be affecting other parts of the code.
Better Testing: Pure functions can be tested in isolation without needing to set up a lot of context or worry about the state of the program.
Reusable: You can reuse pure functions in different parts of your code because you know they don’t depend on or affect any external data.
Safer in Multi-Threading: Since pure functions don’t modify shared variables, they’re safe to run in parallel, which is crucial in multi-threaded or distributed systems.
Conclusion
Pure functions are a great tool for writing clean, predictable, and easy-to-test code in Python. While they aren’t always necessary, using them where you can brings a lot of benefits to your programming. By ensuring your functions are pure, you make your code more readable, maintainable, and less prone to unexpected behavior.
So next time you’re writing a function, ask yourself: “Can I make this a pure function?” If you can, you’ll find your code becomes more reliable and easier to work with!