What is function overloading? Multiple functions with the same name are supported, but the number or type of arguments are different. When calling, the interpreter will call the corresponding function according to the number or type of arguments.

This feature is implemented in many languages, such as C++, Java, etc. Python does not support it. In this article, there are a few tricks to getting Python to support similar functionality.

Different number of parameters

How does C++ implement overloading in this case

#include <iostream>
using namespace std;

int func(int a)
{
	cout << 'One parameter' << endl;
}

int func(int a, int b)
{
	cout << 'Two parameters' << endl;
}

int func(int a, int b, int c)
{
	cout << 'Three parameters' << endl;
}
Copy the code

If Python were to define functions in a similar manner, no error would be reported, except that the later function definition would override the previous one, failing to achieve the effect of overloading.

>>> def func(a):
...     print('One parameter')... >>> def func(a, b): ...print('Two parameters')... >>> def func(a, b, c): ...print('Three parameters')... >>> func(1) Traceback (most recent call last): File"<stdin>", line 1, in <module>
TypeError: func() missing 2 required positional arguments: 'b' and 'c'
>>> func(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'c'
>>> func(1, 2, 3)
Three parameters
Copy the code

But as we know, Python functions have very flexible parameters, and we can define just one function to do the same thing, like this

>>> def func(*args):
...     if len(args) == 1:
...         print('One parameter')...elif len(args) == 2:
...         print('Two parameters')...elif len(args) == 3:
...         print('Three parameters')...else:...print('Error')... >>> func(1) One parameter >>> func(1, 2) Two parameters >>> func(1, 2, 3) Three parameters >>> func(1, 2, 3, 4) ErrorCopy the code

Different parameter types

Again, how does C++ overloading work in the current case

#include <iostream>
using namespace std;

int func(int a)
{
	cout << 'Int: ' << a << endl;
}

int func(float a)
{
	cout << 'Float: ' << a << endl;
}
Copy the code

In the code, func supports two types of arguments: integer and floating point. When called, the interpreter looks for the appropriate function based on the parameter type. Python implements similar functionality with the functools. singleDispatch decorator.

from functools import singledispatch

@singledispatch
def func(a):
	print(f'Other: {a}')

@func.register(int)
def _(a):
	print(f'Int: {a}')

@func.register(float)
def _(a):
	print(f'Float: {a}')

if __name__ == '__main__':
	func('zzz') func (1) func (1.2)Copy the code

The func function, decorated with functools.singledispatch, binds two other functions according to different parameter types. If the argument type is integer or floating point, one of the corresponding functions of the binding is called; otherwise, itself is called.

The execution result

Other: zzz
Int: 1
Float: 1.2
Copy the code

Note that this method only determines the last function to be called based on the type of the first argument.

See the official documentation for more details on SingleDispatch

https://docs.python.org/3.6/library/functools.html#functools.singledispatch
Copy the code

Note: a function that returns a different value is also a case of overloading. There is no good Python implementation for this, so it is not mentioned

Personally, overloading is designed for flexibility in the language, and there are a lot of clever Python functions, so it’s not necessary to copy this technology, and it feels a little contrary to the Philosophy of Python. So, this article is more about mimicking, and not much about how overloading can be used.

This article was first published on the public account “Little Back end”.