Backport of @functools.singledispatchmethod
decorator [1] from
Python 3.8 to Python 2.7-3.7. These are merely ~30 lines of code, but
why bother yourself with copypasta?
$ pip install singledispatchmethod
The decorator transforms a method into a single-dispatch [2] generic function [3]. Note that since the dispatch happens on the type of the first non-self or non-cls argument, you have to create your function accordingly:
from singledispatchmethod import singledispatchmethod
class Negator:
@singledispatchmethod
def neg(self, arg):
raise NotImplementedError("Cannot negate a")
@neg.register
def _(self, arg: int):
return -arg
@neg.register
def _(self, arg: bool):
return not arg
@singledispatchmethod
supports nesting with other decorators such as
@classmethod
. However, in order to expose dispatcher.register
,
@singledispatchmethod
must be the outer most decorator. Here is
the Negator
class with the neg
methods being class bound:
from singledispatchmethod import singledispatchmethod
class Negator:
@singledispatchmethod
@classmethod
def neg(cls, arg):
raise NotImplementedError("Cannot negate a")
@neg.register
@classmethod
def _(cls, arg: int):
return -arg
@neg.register
@classmethod
def _(cls, arg: bool):
return not arg
The same pattern can be used for other similar decorators, such as
@staticmethod
or @abstractmethod
. Please note, since
@singledispatchmethod
decorator is based on
@functools.singledispatch
, type annotations are supported by
dispatcher.register
only since Python 3.7.
[1] | https://docs.python.org/3.8/library/functools.html#functools.singledispatchmethod |
[2] | https://docs.python.org/3.8/glossary.html#term-single-dispatch |
[3] | https://docs.python.org/3.8/glossary.html#term-generic-function |