Python 3.4 added a “singledispatch” decorator to functools, which provides method overloads. This enables you to perform different operations based on the type of the first argument.
By default, it prefers to work with static methods. This mostly comes from the link above:
import functools class TestClass(object): @functools.singledispatch def test_method(arg): print("Let me just say,", end=" ") print(arg) @test_method.register(int) def _(arg): print("Strength in numbers, eh?", end=" ") print(arg) @test_method.register(list) def _(arg): print("Enumerate this:") for i, elem in enumerate(arg): print(i, elem) if __name__ == '__main__': TestClass.test_method(55555) TestClass.test_method([33, 22, 11])
However, there is a low-impact way to get overloading on instance-methods, too. We’ll just place our own wrapper around the standard singledispatch wrapper, and hijack the bulk of the functionality:
import functools def instancemethod_dispatch(func): dispatcher = functools.singledispatch(func) def wrapper(*args, **kw): return dispatcher.dispatch(args[1].__class__)(*args, **kw) wrapper.register = dispatcher.register functools.update_wrapper(wrapper, func) return wrapper class TestClass2(object): @instancemethod_dispatch def test_method(self, arg): print("2: Let me just say,", end=" ") print(arg) @test_method.register(int) def _(self, arg): print("2: Strength in numbers, eh?", end=" ") print(arg) @test_method.register(list) def _(self, arg): print("2: Enumerate this:") for i, elem in enumerate(arg): print(i, elem) if __name__ == '__main__': t = TestClass2() t.test_method(55555) t.test_method([33, 22, 11])
Aside from superficial changes to the original example, we just added the instancemethod_dispatch function and updated the methods to take a “self” argument.
A special thanks to Zero Piraeus for penning the instancemethod_dispatch method (under the original name of “methdispatch”).