Note

Python - partial() - Simplify function arguments with functools


Overview of the Python partial() function. Specify your Function Arguments Ahead of Time.

partial(func, *args, **kwargs) function can be used to partially "save" elements of a function before actually calling it. We can assign a partial() function to a variable and execute it later in our code. We can "save" this function with all necessary arguments or only some of them (and provide other needed arguments later).

To use partial, you must import it from the functools module.

partial() functions can be confusing without a good use case. I personally had a need to use them when I was creating a function to be called under specific condition with specific arguments. I had access to those arguments in only one place, so I used them to build a partial() function that I was able to call later.

Please consider the examples below to better understand this.


from functools import partial

def power(number, exponent):
    return number ** exponent

square = partial(power, exponent=2)

print(square(2), "|", square(5))  # 4 | 25

Output:

4 | 25

Simple example of partial function where we "saved" a function power with default argument for exponent. We provided argument number later.


Partially Applying a Function with All Arguments

from functools import partial

def power(number, exponent):
    return number ** exponent

my_square_10 = partial(power, number=10, exponent=2)

print(my_square_10())  # 100

Output:

100

Here, we saved both arguments in partial function, so we could just execute it later without anything else. Please note that we are actually executing this function - ().


Understanding How partial "Bakes" Arguments

Important thing to remember is that, partial arguments works similarly to function default arguments. They are "baked" while being defined. The example below explains it better.

from functools import partial

def multiply(item, multiplier):
    return item * multiplier

my_item = ["a"]
my_multiplier = 2

my_partial = partial(multiply, my_item, my_multiplier)

print(my_partial())  # ['a', 'a']

my_item = ["a", "b"]

print(my_partial())  # ['a', 'a']

Output:

['a', 'a']
['a', 'a']

Even though we reassigned my_item before the second use, it didn't change the output because partial() "bakes in" a reference to the original object (in this case, the list ["a"]) when it is defined, so any reassignment of my_item does not impact the partial function’s behavior.


Mutating an Argument in a partial Function

But we need to remember that we can still mutate this object (if it is mutable). This happens because the partial function holds a reference to the original object rather than creating a new copy.

from functools import partial

def multiply(item, multiplier):
    return item * multiplier

my_item = ["a"]
my_multiplier = 2

my_partial = partial(multiply, my_item, my_multiplier)

print(my_partial())  # ['a', 'a']

my_item.append("b")

print(my_partial())  # ['a', 'b', 'a', 'b']

Output:

['a', 'a']
['a', 'b', 'a', 'b']

Here we mutated my_item by appending a letter to it and because memory address didn't change, change is reflected in second call.


Key Points to Remember about partial()

  • Flexible Argument Handling: partial allows you to bake some or all arguments in a function, making it useful for specific scenarios like callbacks.

  • "Baking" Behavior: Like function defaults, partial arguments are "baked" at the time of creation, so later reassignment does not affect them.

  • Mutable Objects: If an argument in partial is a mutable object, changes to the object will reflect in the partial function because it holds a reference, not a copy.

I hope you found this helpful! If you have any feedback, questions or requests, please reach out to me through Contact page!

Thank You Image


You might also be interested in: