Online Book Reader

Home Category

Learning Python - Mark Lutz [256]

By Root 1503 0
chapter, let’s look at one last example of argument matching at work. The code you’ll see here is intended for use in Python 2.6 or earlier (it works in 3.0, too, but is pointless there): it uses both the *args arbitrary positional tuple and the **args arbitrary keyword-arguments dictionary to simulate most of what the Python 3.0 print function does.

As we learned in Chapter 11, this isn’t actually required, because 2.6 programmers can always enable the 3.0 print function with an import of this form:

from __future__ import print_function

To demonstrate argument matching in general, though, the following file, print30.py, does the same job in a small amount of reusable code:

"""

Emulate most of the 3.0 print function for use in 2.X

call signature: print30(*args, sep=' ', end='\n', file=None)

"""

import sys

def print30(*args, **kargs):

sep = kargs.get('sep', ' ') # Keyword arg defaults

end = kargs.get('end', '\n')

file = kargs.get('file', sys.stdout)

output = ''

first = True

for arg in args:

output += ('' if first else sep) + str(arg)

first = False

file.write(output + end)

To test it, import this into another file or the interactive prompt, and use it like the 3.0 print function. Here is a test script, testprint30.py (notice that the function must be called “print30”, because “print” is a reserved word in 2.6):

from print30 import print30

print30(1, 2, 3)

print30(1, 2, 3, sep='') # Suppress separator

print30(1, 2, 3, sep='...')

print30(1, [2], (3,), sep='...') # Various object types

print30(4, 5, 6, sep='', end='') # Suppress newline

print30(7, 8, 9)

print30() # Add newline (or blank line)

import sys

print30(1, 2, 3, sep='??', end='.\n', file=sys.stderr) # Redirect to file

When run under 2.6, we get the same results as 3.0’s print function:

C:\misc> c:\python26\python testprint30.py

1 2 3

123

1...2...3

1...[2]...(3,)

4567 8 9

1??2??3.

Although pointless in 3.0, the results are the same when run there. As usual, the generality of Python’s design allows us to prototype or develop concepts in the Python language itself. In this case, argument-matching tools are as flexible in Python code as they are in Python’s internal implementation.

Using Keyword-Only Arguments

It’s interesting to notice that this example could be coded with Python 3.0 keyword-only arguments, described earlier in this chapter, to automatically validate configuration arguments:

# Use keyword-only args

def print30(*args, sep=' ', end='\n', file=sys.stdout):

output = ''

first = True

for arg in args:

output += ('' if first else sep) + str(arg)

first = False

file.write(output + end)

This version works the same as the original, and it’s a prime example of how keyword-only arguments come in handy. The original version assumes that all positional arguments are to be printed, and all keywords are for options only. That’s almost sufficient, but any extra keyword arguments are silently ignored. A call like the following, for instance, will generate an exception with the keyword-only form:

>>> print30(99, name='bob')

TypeError: print30() got an unexpected keyword argument 'name'

but will silently ignore the name argument in the original version. To detect superfluous keywords manually, we could use dict.pop() to delete fetched entries, and check if the dictionary is not empty. Here is an equivalent to the keyword-only version:

# Use keyword args deletion with defaults

def print30(*args, **kargs):

sep = kargs.pop('sep', ' ')

end = kargs.pop('end', '\n')

file = kargs.pop('file', sys.stdout)

if kargs: raise TypeError('extra keywords: %s' % kargs)

output = ''

first = True

for arg in args:

output += ('' if first else sep) + str(arg)

first = False

file.write(output + end)

This works as before, but it now catches extraneous keyword arguments, too:

>>> print30(99, name='bob')

TypeError: extra keywords: {'name': 'bob'}

This version of the function runs under Python 2.6, but it requires four more lines of code than the keyword-only version. Unfortunately, the extra code is required

Return Main Page Previous Page Next Page

®Online Book Reader