There are two ways to do this:
- Delegation Already in Python. Most pythons. Does not work for built-in types. Not quite what you are looking for.
- Separate shipping . Another PEP. Works for built-in types. Exactly what you are looking for.
Delegation
Usually you delegate responsibility for the object that you are affecting, and you do not implement the logic in your function.
Here is an example: len . The len implementation is very simple:
def len(obj): return obj.__len__()
Different types ( str , list , tuple ...) have different implementations, but they all work with the same function.
Now, if I want to define my own type that works with len , I can do:
class MyTypeOfLength3(object): def __len__(self): return 3 o = MyTypeOfLength3() print len(o)
In your case, you will implement something similar to len .
(Note: this is not the actual code for len , but it is more or less equivalent.)
Single dispatch
Of course, in some cases this can be impractical. If this is your case, then the "Single Dispatch" PEP 443 is probably what you are looking for.
He offers a new decorator that will accomplish what you are looking for:
>>> from functools import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) ... >>> @fun.register(int) ... def _(arg, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> @fun.register(list) ... def _(arg, verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem)
Once you have defined your function as such, you can call fun(something) and Python will find the correct implementation ( int or list here), disconnecting the default implementation def fun(...): ...
Therefore, you only need to decorate your original function, and you're done, your users can add their own types.
Note: as pointed out in the comments, singledispatch already implemented in Python, it is pkgutil.simplegeneric