Emulating the Python 3.0 print Function

To round out the 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:

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

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.