Named Arguments

When there are a lot of parameters it is easy to get confused about the correct order. Instead we can refer to parameters by name, and even assign them a default value just in case one was not provided by the calling program. Now the parameters can be specified in any order, and can be omitted.

>>> def repeat(msg='<empty>', num=1):

'Alice'

>>> repeat(num=5, msg='Alice') 'AliceAliceAliceAliceAlice'

These are called keyword arguments. If we mix these two kinds of parameters, then we must ensure that the unnamed parameters precede the named ones. It has to be this way, since unnamed parameters are defined by position. We can define a function that takes an arbitrary number of unnamed and named parameters, and access them via an in-place list of arguments *args and an in-place dictionary of keyword arguments **kwargs.

>>> def generic(*args, **kwargs): ... print args ... print kwargs

>>> generic(1, "African swallow", monty="python") (1, 'African swallow') {'monty': 'python'}

When *args appears as a function parameter, it actually corresponds to all the unnamed parameters of the function. As another illustration of this aspect of Python syntax, consider the zip() function, which operates on a variable number of arguments. We'll use the variable name *song to demonstrate that there's nothing special about the name *args.

>>> song = [['four', 'calling', 'birds'], ... ['three', 'French', 'hens'],

[('four', 'three', 'two'), ('calling', 'French', 'turtle'), ('birds', 'hens', 'doves')] >>> zip(*song)

[('four', 'three', 'two'), ('calling', 'French', 'turtle'), ('birds', 'hens', 'doves')]

It should be clear from this example that typing *song is just a convenient shorthand, and equivalent to typing out song[0], song[1], song[2].

Here's another example of the use of keyword arguments in a function definition, along with three equivalent ways to call the function:

... tokens = nltk.word_tokenize(text)

... freqdist = nltk.FreqDist(t for t in tokens if len(t) >= min)

>>> fw = freq_words('ch01.rst', min=4, num=10)

>>> fw = freq_words('ch01.rst', num=10, min=4)

A side effect of having named arguments is that they permit optionality. Thus we can leave out any arguments where we are happy with the default value: freq_words('ch01.rst', min=4), freq_words('ch01.rst', 4). Another common use of optional arguments is to permit a flag. Here's a revised version of the same function that reports its progress if a verbose flag is set:

>>> def freq_words(file, min=1, num=10, verbose=False):

... if trace: print "Read in %d characters" % len(file) ... for word in nltk.word_tokenize(text):

if trace and freqdist.N() % 100 == 0: print ". if trace: print return freqdist.keys()[:num]

Caution!

Take care not to use a mutable object as the default value of a parameter. A series of calls to the function will use the same object, sometimes with bizarre results, as we will see in the discussion of debugging later.

Was this article helpful?

0 0

Post a comment