Partial functions in python functools.partial. With applications and examples.
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 * ypartial_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 + ypartial_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 key
method 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.23606797749979sorted(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.
- 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: