DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. Function Overloading With singledispatch in Python 3

Function Overloading With singledispatch in Python 3

Can't do function overloading in Python? Think again.

Mike Driscoll user avatar by
Mike Driscoll
·
Jun. 23, 16 · Tutorial
Like (2)
Save
Tweet
Share
3.38K Views

Join the DZone community and get the full member experience.

Join For Free

Python fairly recently added partial support for function overloading in Python 3.4. They did this by adding a neat little decorator to the functools module called singledispatch. This decorator will transform your regular function into a single dispatch generic function. Note however that singledispatch only happens based on the first argument’s type. Let’s take a look at an example to see how this works!

from functools import singledispatch


@singledispatch
def add(a, b):
    raise NotImplementedError('Unsupported type')


@add.register(int)
def _(a, b):
    print("First argument is of type ", type(a))
    print(a + b)


@add.register(str)
def _(a, b):
    print("First argument is of type ", type(a))
    print(a + b)


@add.register(list)
def _(a, b):
    print("First argument is of type ", type(a))
    print(a + b)


if __name__ == '__main__':
    add(1, 2)
    add('Python', 'Programming')
    add([1, 2, 3], [5, 6, 7])

Here we import singledispatch from functools and apply it to a simple function that we call add. This function is our catch-all function and will only get called if none of the other decorated functions handle the type passed. You will note that we currently handle integers, strings, and lists as the first argument. If we were to call our add function with something else, such as a dictionary, then it would raise a NotImplementedError.

Try running the code yourself. You should see output that looks like this:

First argument is of type  <class 'int'>
3
First argument is of type  <class 'str'>
PythonProgramming
First argument is of type  <class 'list'>
[1, 2, 3, 5, 6, 7]
Traceback (most recent call last):
  File "overloads.py", line 30, in <module>
    add({}, 1)
  File "/usr/local/lib/python3.5/functools.py", line 743, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "overloads.py", line 5, in add
    raise NotImplementedError('Unsupported type')
NotImplementedError: Unsupported type

As you can see, the code works exactly as advertised. It calls the appropriate function based on the first argument’s type. If the type isn’t handled, then we raise a NotImplementedError. If you want to know what types we are currently handling, you can add the following piece of code to the end of the file, preferably before the line that raises an error:

print(add.registry.keys())

This will print out something like this:

dict_keys([<class 'str'>, <class 'int'>, <class 'list'>, <class 'object'>])

This tells us that we can handle strings, integers, lists, and objects (the default). The singledispatch decorator also supports decorator stacking. This allows us to create an overloaded function that can handle multiple types. Let’s take a look:

from functools import singledispatch
from decimal import Decimal


@singledispatch
def add(a, b):
    raise NotImplementedError('Unsupported type')


@add.register(float)
@add.register(Decimal)
def _(a, b):
    print("First argument is of type ", type(a))
    print(a + b)


if __name__ == '__main__':
    add(1.23, 5.5)
    add(Decimal(100.5), Decimal(10.789))

This basically tells Python that one of the add function overloads can handle float and decimal. Decimal types as the first argument. If you run this code, you should see something like the following:

First argument is of type  <class 'float'>
6.73
First argument is of type  <class 'decimal.Decimal'>
111.2889999999999997015720510
dict_keys([<class 'float'>, <class 'int'>, <class 'object'>, <class 'decimal.Decimal'>

You may have noticed this already, but because of the way all these functions were written, you could stack the decorators to handle all the cases in the previous example and this example into one overloaded function. However, in a normal overloaded case, each overload would call different code instead of doing the same thing.

Wrapping Up

Function overloading has been around for quite some time in other languages. It’s good to see that Python has added it as well. Of course, some of the other languages allow multi-dispatch instead of single dispatch, which means that they look at more than one of the argument’s types. Hopefully, Python will add this functionality in a future release. Also, note that you can register lambdas and pre-existing functions with singledispatch. See the documentation for full details.

Related Reading

  • Python documentation for the functools module
  • PEP 0443 – Single-dispatch generic functions
  • Single Dispatch generic functions article
  • Python 3.4 single dispatch generic function
Python (language)

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 5 Java REST API Frameworks
  • Fraud Detection With Apache Kafka, KSQL, and Apache Flink
  • Select ChatGPT From SQL? You Bet!
  • ChatGPT: The Unexpected API Test Automation Help

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: