I would like to use overloading in Python. I know it's not possible by design (Python is dynamically typed language), there is quite good thread here on this topic. That's why I could use something like multiple dispatch (multimethods). And I'm thinking about the best solution, that would implement multiple dispatch for any function or class method. Is there any solution that is natively included in Python?
Using singledispatch (added to Python in 3.4) is not enough in my case (because only the type of the first argument is considered and I need multiple).
I also know that I could use keyword arguments (i.e. having single function and drive the behavior by checking all arguments), but it's getting complicated when you have a lot of arguments and combinations.
So far, I was able to find these two libraries (not included in the Python Standard Library):
- multimethod - provides a decorator for adding multiple argument dispatching to functions, one can use the same style of registration as functools.singledispatch, works well with annotations, can even work with annotated predicates or offers special
multimeta
namespace for classes - multipledispatch - provides also decorator for multiple argument dispatching, does not work with annotations and looks not so powerful to me in comparison with the previous library
The basic usage looks like:
from multimethod import multimethod
@multimethod
def add(x: int, y: int):
...
@multimethod
def add(x: str, y: str):
...
or
from multipledispatch import dispatch
@dispatch(int, int)
def add(x, y):
...
@dispatch(str, str)
def add(x, y):
...
This functionality seems very similar.
I have mainly two questions:
- Does one of those multiple dispatch implementations bring any (dis)advantage over the other? (E.g. supported types, speed, performance, limitations, ...) It seems comparable but I was not sure about this, since the latter (multipledispatch) seems to be more popular (checking GitHub stars) but less maintained (and I would even say less mature).
- Is there any other solution (even such that is included in the Python Standard Library)?
f(x: int, y: str): return 1
andf(y: str, x: int): return 2
. You can differentiate these by argument orderf(1, "one")
vsf("one", 1)
, but keywords abandon order and are thus ambiguousf(y = "one", x = 1)
. The only way to "fix" this would be to force the user to adhere to some argument name order. Correct me if I'm wrong, but I also can't think of a static language with function overloading that does it for named parameters. – Filthy