Descubrí que el módulo functools de Python 3 tiene dos métodos muy similares: partial y partialmethod parcial.
¿Alguien puede proporcionar buenos ejemplos del uso de cada uno?
partial se utiliza para congelar argumentos y palabras clave. Crea un nuevo objeto invocable con aplicación parcial de los argumentos y palabras clave dados.
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.Esto es útil cuando desea asignar una lista de números a una función pero manteniendo un argumento congelado.
# [adding(4,3), adding(4,2), adding(4,5), adding(4,7)] add_list = list(map(adding, [3,2,5,7])) partialmethod se introdujo en python 3.4 y está destinado a usarse en una clase como una definición de método en lugar de ser directamente invocable.
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())Como dijo @HaiVu en su comentario, la llamada parcial en una definición de clase creará un método estático, mientras que el método parcial creará un nuevo método vinculado que, cuando se llame, se pasará a sí mismo como el primer argumento.
No estaba seguro de si la c.get_partialmethod()() a continuación funcionaría o no, pero como z33k mencionó en los comentarios, no funciona:
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