tags:

views:

82

answers:

2

What are the advantages of having Optional args in Python. Instead of overloading one function (or method) with args + optional args, wouldn't Polymorphism with Inheritance suffice?

I am just trying to understand the burning reason to have this feature. or is it the case of being able to do one thing many ways?

P.S: I can see that it makes sense to have it in functional programming, to avoid having to define many functions practically doing almost the same thing, but are there any other...

+6  A: 

Optional args have little to do with polymorphism (and don't even need you to have classes around!-) -- it's just (main use!) that often you have "rarely needed" arguments for choices that are generally made in a certain way, but it might be useful for the caller to set differently.

For example, consider built-in open. Most often, you open text files rather than binary opens, you open them for reading rather than for writing, and you're happy with the default buffering -- so, you just open('thefile.txt') and live happily ever after. Being able to specify the way in which you want to open (binary, for overwrite, for append, ...) as the second (optional) argument, instead of its default 'r' value, is of course often useful. Once in a blue moon you want a file object with peculiar buffering options, and then having the buffering as the third (optional) argument (with a default value of course) pays big dividends... without it being in your way for the vast majority of the files you open!

Inheritance and polymorphism would not really help one bit in getting the convenience of with open('blah.txt') as f: so concisely, while still allowing the same built-in function to serve many more use cases (e.g., when you need to open a file for binary append without any buffering... maybe once a year if you code a lot;-). And of course the convenience principles that apply to such built-in functions apply to the functions you write just as well!-)

Alex Martelli
+4  A: 

Optional arguments in Python serve multiple purposes, but most often they are a mechanism to provide defaults where there are sensible and infrequently varied values exist. E.g.:

def open_http_connection(url, port=80, timeout=2):
  #...

A subtle variation is when multiple behaviors for a method are required based on the arguments provided, often using arity (number of arguments) or keyword arguments.

# Example of arity based optional arguments
def do_something(*args):
  if not args:
    do_something1()
  elif len(args)==1:
    do_something2(args[0])
  else:
    do_something3(*args)

It may be helpful to study how variable positional and keyword arguments are specified in python: here.

These methods for specifying optional and variable numbers of arguments are not as semantically complex as method overloading in statically typed object-oriented languages or various forms of multiple-dispatch as found in functional programming languages. Python uses dynamic typing (sometimes called duck typing), so these forms of dispatch are not idiomatic or terribly useful. (This is not often seen as a limitation or disadvantage, though Python is certainly flexible enough to support multi-methods if one must have them.)

Kevin Jacobs