Function overloading in Python: Missing [closed]
Asked Answered
S

5

64

As function overloading says:

Function overloading is absent in Python.

As far as I feel this a big handicap since its also an object-oriented (OO) language. Initially I found that unable to differentiate between the argument types was difficult, but the dynamic nature of Python made it easy (e.g. list, tuples, strings are much similar).

However, counting the number of arguments passed and then doing the job is like an overkill.

Any pythonic way to do this?

Simeon answered 9/4, 2009 at 7:57 Comment(9)
So? What do you think you need overloading for?Dialyser
Voting to close as not a real question. That's not to say it's not a potentially valid point, but it's not a question.Bromley
Well, then use a language that provides overloading...Plexor
Also voting to close. This is either an implied question or a rant, either of which is hard to answer.Maxfield
It could have been a question if I just added -- "any Pythonic way to do this?". However I feel this is implied in my post.Simeon
Guido has actually provided a pythonic solution to overloading artima.com/weblogs/viewpost.jsp?thread=155514 Though other solutions exist, like the following ibm.com/developerworks/library/l-pydisp.html I think Peak or something similar had a fairly complex one.Salinas
@Simeon Explicit is better than implicit.Peculation
@konpsych oh my god are you kidding me? This is EXACTLY why people make fun of programmers and Stack Overflow. Human conversation isn't a programming language! Jesus Christ.Fulbright
Related (not duplicate): How can I detect duplicate method names in a Python class?Ionian
W
33

As unwind noted, keyword arguments with default values can go a long way.

I'll also state that in my opinion, it goes against the spirit of Python to worry a lot about what types are passed into methods. In Python, I think it's more accepted to use duck typing -- asking what an object can do, rather than what it is.

Thus, if your method may accept a string or a tuple, you might do something like this:

def print_names(names):
    """Takes a space-delimited string or an iterable"""
    try:
        for name in names.split(): # string case
            print name
    except AttributeError:
        for name in names:
            print name

Then you could do either of these:

print_names("Ryan Billy")
print_names(("Ryan", "Billy"))

Although an API like that sometimes indicates a design problem.

Whatever answered 9/4, 2009 at 9:48 Comment(2)
Then an example without design problem please.Golub
Granted, it's a bit contrived, but this sums a list of int/str and considers [a-z]/i to have values 1-26: gist.github.com/cmattoon/abeed5fb8367b0b869cfPlenitude
E
36

Now, unless you're trying to write C++ code using Python syntax, what would you need overloading for?

I think it's exactly opposite. Overloading is only necessary to make strongly-typed languages act more like Python. In Python you have keyword argument, and you have *args and **kwargs.

See for example: What is a clean, Pythonic way to have multiple constructors in Python?

Eade answered 9/4, 2009 at 9:36 Comment(2)
Your assessment that overloading is "hack-work for handicapped languages" seems overly polarised and overlooks the benefit of static typing, and its suitability to a different type of deployment. Stefano Borini's answer that "..function overloading is based on the idea that passing different types you will execute different code. If you have a dynamically typed language like python, you should not distinguish by type" is more informative and helpful I think.Predictory
Of course, you can use variable arguments in C++, too, yet overloading is used to keep code clean. As in, one function does one thing rather than having a single function littered with if statements trying to figure out what to do based on what was passed in.Pitcher
W
33

As unwind noted, keyword arguments with default values can go a long way.

I'll also state that in my opinion, it goes against the spirit of Python to worry a lot about what types are passed into methods. In Python, I think it's more accepted to use duck typing -- asking what an object can do, rather than what it is.

Thus, if your method may accept a string or a tuple, you might do something like this:

def print_names(names):
    """Takes a space-delimited string or an iterable"""
    try:
        for name in names.split(): # string case
            print name
    except AttributeError:
        for name in names:
            print name

Then you could do either of these:

print_names("Ryan Billy")
print_names(("Ryan", "Billy"))

Although an API like that sometimes indicates a design problem.

Whatever answered 9/4, 2009 at 9:48 Comment(2)
Then an example without design problem please.Golub
Granted, it's a bit contrived, but this sums a list of int/str and considers [a-z]/i to have values 1-26: gist.github.com/cmattoon/abeed5fb8367b0b869cfPlenitude
C
21

You don't need function overloading, as you have the *args and **kwargs arguments.

The fact is that function overloading is based on the idea that passing different types you will execute different code. If you have a dynamically typed language like Python, you should not distinguish by type, but you should deal with interfaces and their compliance with the code you write.

For example, if you have code that can handle either an integer, or a list of integers, you can try iterating on it and if you are not able to, then you assume it's an integer and go forward. Of course it could be a float, but as far as the behavior is concerned, if a float and an int appear to be the same, then they can be interchanged.

Cozza answered 9/4, 2009 at 8:52 Comment(1)
Overloading isn't strictly about types, it's also about number of arguments. For instance, I may want my accessor and mutator (or "getter" and "setter" if you prefer) to share a single method name, but they are clearly doing separate things based on the presence of an argument. This has nothing to do with the type of argument.Pitcher
S
6

Oftentimes you see the suggestion use use keyword arguments, with default values, instead. Look into that.

Shirring answered 9/4, 2009 at 8:8 Comment(0)
L
6

You can pass a mutable container datatype into a function, and it can contain anything you want.

If you need a different functionality, name the functions differently, or if you need the same interface, just write an interface function (or method) that calls the functions appropriately based on the data received.

It took a while to me to get adjusted to this coming from Java, but it really isn't a "big handicap".

Linebacker answered 9/4, 2009 at 8:53 Comment(1)
hi @lprsd! can you provide a simple example of interface function. ofcourse it seems trivial enough, but i want to see how it's done by those who know to ensure i won't miss anything crucial while DIY-ing. thanks :)Discriminant

© 2022 - 2024 — McMap. All rights reserved.