I found out that functools
module of Python 3 has two very similar methods: partial
and partialmethod
.
Can someone provide good examples of using each one?
partial
is used to freeze arguments and keywords. It creates a new callable object with partial application of the given arguments and keywords.
from functools import partial
from operator import add
# add(x,y) normally takes two argument, so here, we freeze one argument and create a partial function.
adding = partial(add, 4)
adding(10) # outcome will be add(4,10) where `4` is the freezed arguments.
This is useful when you want to map a list of numbers to a function but maintaining one argument frozen.
# [adding(4,3), adding(4,2), adding(4,5), adding(4,7)]
add_list = list(map(adding, [3,2,5,7]))
partialmethod
was introduced in python 3.4 and it is meant to be used in a class as a method definition rather than been directly callable
from functools import partialmethod
class Live:
def __init__(self):
self._live = False
def set_live(self,state:'bool'):
self._live = state
def __get_live(self):
return self._live
def __call__(self):
# enable this to be called when the object is made callable.
return self.__get_live()
# partial methods. Freezes the method `set_live` and `set_dead`
# with the specific arguments
set_alive = partialmethod(set_live, True)
set_dead = partialmethod(set_live, False)
live = Live() # create object
print(live()) # make the object callable. It calls `__call__` under the hood
live.set_alive() # Call the partial method
print(live())
As @HaiVu said in his comment partial called in a class definition will create a staticmethod, while partialmethod will create a new bound method which when called will be passed self as the first argument.
I wasn't sure whether the c.get_partialmethod()()
call below would work or not, but as z33k mentioned in the comments, it doesn't:
import functools
class Cell:
def __init__(self):
pass
def foo(self, x):
print(x)
def get_partial(self):
return functools.partial(self.foo, True)
def get_partialmethod(self):
return functools.partialmethod(self.foo, True)
c = Cell()
print(c.get_partial()) # functools.partial(<bound method Cell.foo of <__main__.Cell object at 0x000001F3BF853AC0>>, True)
print(c.get_partialmethod()) # functools.partialmethod(<bound method Cell.foo of <__main__.Cell object at 0x000001F3BF853AC0>>, True, )
c.get_partial()() # Prints True
c.get_partialmethod()() # TypeError: 'partialmethod' object is not callable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With