Overloaded functions in Python Overloaded functions in Python python python

Overloaded functions in Python


EDIT For the new single dispatch generic functions in Python 3.4, see http://www.python.org/dev/peps/pep-0443/

You generally don't need to overload functions in Python. Python is dynamically typed, and supports optional arguments to functions.

def myfunction(first, second, third = None):    if third is None:        #just use first and second    else:        #use all threemyfunction(1, 2) # third will be None, so enter the 'if' clausemyfunction(3, 4, 5) # third isn't None, it's 5, so enter the 'else' clause


In normal Python you can't do what you want. There are two close approximations:

def myfunction(first, second, *args):    # 'args' is a tuple of extra argumentsdef myfunction(first, second, third=None):    # 'third' is optional

However, if you really want to do this, you can certainly make it work (at the risk of offending the traditionalists ;o). In short, you would write a wrapper(*args) function that checks the number of arguments and delegates as appropriate. This kind of "hack" is usually done via decorators. In this case, you could achieve something like:

from typing import overload@overloaddef myfunction(first):    ....@myfunction.overloaddef myfunction(first, second):    ....@myfunction.overloaddef myfunction(first, second, third):    ....

And you'd implement this by making the overload(first_fn) function (or constructor) return a callable object where the __call__(*args) method does the delegation explained above and the overload(another_fn) method adds extra functions that can be delegated to.

You can see an example of something similar here http://acooke.org/pytyp/pytyp.spec.dispatch.html, but that is overloading methods by type. It's a very similar approach...

And something similar (using argument types) is being added to Python 3 - PEP 443 -- Single-dispatch generic functions


Yes, it's possible. I wrote the code below in Python 3.2.1:

def overload(*functions):    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

Usage:

myfunction=overload(no_arg_func, one_arg_func, two_arg_func)

Note that the lambda returned by the overload functions choose a function to call depending on the number of unnamed arguments.

The solution isn't perfect, but at the moment I can't write anything better.