Partial functions in python functools.partial. With applications and examples.

Siddharth Kshirsagar
4 min readAug 2, 2020

--

Photo by Marek Szturc on Unsplash

What are partial functions. understanding functools.partial and its applications and use-cases.

functools.partial(func,*args,**kwargs) returns a new partial object when called will behave like func called with positional arguments(*args) and keywords arguments (*kwargs)

from functools import partial
def multiply(x,y):
return x * y
partial_func = partial(multiply,5)

In this example we have defined a partial function object partial_func.

Now First let’s ponder over what are partial objects.

Partial objects are callable objects created by the functools.partial().

They have three attributes.

1. partial.func: A callable object or a function. And calls to the partial object will be forwarded to func with new arguments and keywords,

2. partial.args: The leftmost arguments prepended to the positional arguments provided to a partial object call.

3. partial.keywords:The keyword arguments that will be supplied when the partial object is called.

Examples and Applications

Example 1:

def sum(x,y):
return x + y
partial_sum = partial(sum,7)
print(partial_sum(13))
#Output: 20

Example 2: In a “pipe-lined” sequence of function calls(returned value from one function is passed as argument for next function). Sometimes a function in such a pipeline requires a single argument, but the function in immediate upstream gives two parameters. In this case partials are very useful.

Consider you have a bunch of data and you want to sort the data according to a particular point.

from numpy.random import randint
import numpy as np
data = randint(1,100,(10,2))
target = np.array([2,4])
# sorting some data by each data point's distance from some target
def euclid_distance(p1,p2):
x1,y1 = p1
x2,y2 = p2
return np.sqrt(pow(x2 - x1,2) + pow(y2 - y1,2))

we can use sorted(data,key) but the problem with this is the keymethod of sorted accepts only one parameter and the below statement will throw an error

sorted(data,key = euclid_distance)

we can use lambda method but the problem with this anonymous function is that the point (target) to which we are doing the comparison should be hard coded.

sorted(data, key = lambda x:  np.sqrt(pow(2 - x[0],2) + pow(4 - x[1],2)))

In this case partial comes to rescue.

from functools import partial
partial_euclid = partial(euclid_distance,target)
partial_euclid((1,2))
# Output: 2.23606797749979
sorted(data,key=partial_euclid)
# Output: Sorted array

Example 3: Instead of iterating over a file by lines, you want to iterate over a collection of fixed size records or chunks.

from functools import partial
RECORD_SIZE = 45
with open("example_text.txt",'rt') as f:
# partial takes function fileobject.read and RECORD_SIZE and this is converted
# into an iterator
chunk_records = iter(partial(f.read,RECORD_SIZE),"")
for records in chunk_records:
print(records)

The chunk_records object is an iterable that will produce fixed size chunks until the end of the file is reached.

Internal Working of this function.

  1. the iter() creates iterator if we pass a callable and sentinel value.

2. The resulting iterator simply calls the supplied callable over and over again until the sentinel value is reached.

3. The functools.partial is used to create a callable that reads a fixed number of strings from a file each time it is called. The sentinel “” is returned when a end of file is reached.

References:

--

--

Responses (1)