0

I know Python doesn't support overloading, but I'm not sure how to do the following task in Python without resorting to different method names.

I have two methods which require different set of parameters:

def get_infobox_from_list(templates):
  for template in templates:
    if get_base_length(template[0]) >= 0:
      return template
  return None

def get_infobox(site, name):
  # first try box template
  infobox = get_infobox_from_list(get_templates(site, "{}/Box".format(name)))
  if infobox is None:
    infobox = get_infobox_from_list(get_templates(site, name))
  return infobox

Both methods do similar things (they get you a template), but their parameters are different. Now I've read that Python is usually allowing this by using default arguments.

That might be helping sometimes, but the difference is, that the method either needs two parameters (site and name) or one (templates) but no other combination (like site and templates, only name, only site, name and templates or all three).

Now in Java I could simply define those two overloading methods. So if somebody is calling either one of them their parameters must match without defining to many or to few. So my question is, how should it be done in Python really.

4
  • 3
    Why don't you want to just make two separate methods with different names? Commented Jan 26, 2014 at 22:38
  • 1
    Overloading in Python, if you call it that way, is not that simple, especially not in the global scope. AFAIK you really have to hack into some advanced stuff. The difference to Java is that Java is statically typed and the JVM knows which of the methods you are calling (because of the argument types). Python does not. Commented Jan 26, 2014 at 22:41
  • Are the calls to get_infobox_from in get_infobox supposed to be calls to get_infobox_from_list, or is get_infobox_from yet another related function that's kicking around? Assuming the former, I'd probably rename get_infobox_from_list anyway in this example. It returns the first thing from its input whose length is non-negative, I don't see that its name necessarily needs to be anything to do with infobox. Call it find_usable_template or something. Commented Jan 27, 2014 at 0:16
  • @SteveJessop that get_base_length function does return basically what type of infobox it is. If it returns a negative value, the checked template isn't anything the program can understand. And I missspelled get_infobox_from, it should be get_infobox_from_list. Commented Jan 27, 2014 at 11:22

2 Answers 2

3

You could try using *args:

def get_infobox_from_list(*args):
    if len(args) == 1:
        return _get_infobox_from_list_template(*args)
    else:
        return _get_infobox_from_list_sitename(*args)

Then you can define the two similar sub-functions. But this is pretty awkward, and suggests that two separate methods with different names might be a better fit.

Sign up to request clarification or add additional context in comments.

3 Comments

Although I accepted the other answer (as that answer is explaining it the best way, I would say), your suggestion to use two methods with different names might be really better. In Java overloading wasn't a problem, so it didn't really “hurt” when you had two methods not exactly doing the same with the same name.
Well both of the current answers actually include three separate functions, with a wrapper function controlling which sub-function to call. This suggests that you could cut out the wrapper and call the sub-functions directly.
Yours uses *args while the other uses named parameters. Maybe I'm not enough in Python and *args might be favoured. And yes, I would call the sub-functions directly because the wrapper saves only a few letters.
2

You could use a "wrapper" method (not sure what the correct terminology here is) that passes the parameters along to the correct version of the get_infobox_... function.

def get_infobox(site=None, name=None, templates=None):
    if site is not None and name is not None and templates is None:
        get_infobox_from_site_and_name(site, name)
    elif templates is not None and site is None and name is None:
        get_infobox_from_list(templates)
    else:
        raise Exception # or some particular type of exception

However, I imagine there is a better way to accomplish what you want to do - I've never found a need to resort to a pattern like this in Python. I can't really suggest a better option without understanding why you want to do this in greater detail, though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.