Implementing Partial Application in Python
As mentioned earlier, the functools.partial()
function is the primary way to implement partial application in Python. Here's how you can use it:
from functools import partial
def multiply(a, b):
return a * b
double = partial(multiply, 2)
print(double(5)) ## Output: 10
In this example, we define a multiply()
function that takes two arguments and returns their product. We then use partial()
to create a new function double()
that has the first argument fixed to 2
. When we call double(5)
, the result is 10
because the multiply()
function is called with a=2
and b=5
.
Partial Application with Multiple Arguments
You can also use partial()
to fix multiple arguments of a function:
from functools import partial
def power(base, exponent, sign):
return (base ** exponent) * sign
square_abs = partial(power, exponent=2, sign=1)
print(square_abs(5)) ## Output: 25
print(square_abs(-5)) ## Output: 25
In this example, the power()
function takes three arguments: base
, exponent
, and sign
. We use partial()
to create a new function square_abs()
that has the exponent
fixed to 2
and the sign
fixed to 1
. This means that square_abs()
only requires a single argument, the base
, and it will always return the absolute value of the base raised to the power of 2.
Partial Application with Keyword Arguments
You can also use keyword arguments when calling partial()
:
from functools import partial
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
say_hello = partial(greet, greeting="Hi")
print(say_hello("Alice")) ## Output: Hi, Alice!
In this example, the greet()
function takes two arguments: name
and greeting
. We use partial()
to create a new function say_hello()
that has the greeting
argument fixed to "Hi"
. When we call say_hello("Alice")
, the result is "Hi, Alice!"
.
Partial Application with Classes
You can also use partial application with classes. This can be useful when you have a class with a constructor that takes several arguments, and you want to create instances of the class with some of the arguments already set:
from functools import partial
class Person:
def __init__(self, name, age, city):
self.name = name
self.age = age
self.city = city
def __str__(self):
return f"{self.name}, {self.age}, {self.city}"
new_yorker = partial(Person, city="New York")
alice = new_yorker("Alice", 30)
print(alice) ## Output: Alice, 30, New York
In this example, we define a Person
class with a constructor that takes three arguments: name
, age
, and city
. We then use partial()
to create a new function new_yorker()
that has the city
argument fixed to "New York"
. When we call new_yorker("Alice", 30)
, the result is a Person
object with the name
set to "Alice"
, the age
set to 30
, and the city
set to "New York"
.