Online Book Reader

Home Category

Learning Python - Mark Lutz [324]

By Root 1583 0
when the file is run as a top-level script, not when it is imported:

print('I am:', __name__)

def minmax(test, *args):

res = args[0]

for arg in args[1:]:

if test(arg, res):

res = arg

return res

def lessthan(x, y): return x < y

def grtrthan(x, y): return x > y

if __name__ == '__main__':

print(minmax(lessthan, 4, 2, 1, 5, 6, 3)) # Self-test code

print(minmax(grtrthan, 4, 2, 1, 5, 6, 3))

We’re also printing the value of __name__ at the top here to trace its value. Python creates and assigns this usage-mode variable as soon as it starts loading a file. When we run this file as a top-level script, its name is set to __main__, so its self-test code kicks in automatically:

% python min.py

I am: __main__

1

6

But, if we import the file, its name is not __main__, so we must explicitly call the function to make it run:

>>> import min

I am: min

>>> min.minmax(min.lessthan, 's', 'p', 'a', 'm')

'a'

Again, regardless of whether this is used for testing, the net effect is that we get to use our code in two different roles—as a library module of tools, or as an executable program.

Using Command-Line Arguments with __name__

Here’s a more substantial module example that demonstrates another way that the __name__ trick is commonly employed. The following module, formats.py, defines string formatting utilities for importers, but also checks its name to see if it is being run as a top-level script; if so, it tests and uses arguments listed on the system command line to run a canned or passed-in test. In Python, the sys.argv list contains command-line arguments—it is a list of strings reflecting words typed on the command line, where the first item is always the name of the script being run:

"""

Various specialized string display formatting utilities.

Test me with canned self-test or command-line arguments.

"""

def commas(N):

"""

format positive integer-like N for display with

commas between digit groupings: xxx,yyy,zzz

"""

digits = str(N)

assert(digits.isdigit())

result = ''

while digits:

digits, last3 = digits[:-3], digits[-3:]

result = (last3 + ',' + result) if result else last3

return result

def money(N, width=0):

"""

format number N for display with commas, 2 decimal digits,

leading $ and sign, and optional padding: $ -xxx,yyy.zz

"""

sign = '-' if N < 0 else ''

N = abs(N)

whole = commas(int(N))

fract = ('%.2f' % N)[-2:]

format = '%s%s.%s' % (sign, whole, fract)

return '$%*s' % (width, format)

if __name__ == '__main__':

def selftest():

tests = 0, 1 # fails: −1, 1.23

tests += 12, 123, 1234, 12345, 123456, 1234567

tests += 2 ** 32, 2 ** 100

for test in tests:

print(commas(test))

print('')

tests = 0, 1, −1, 1.23, 1., 1.2, 3.14159

tests += 12.34, 12.344, 12.345, 12.346

tests += 2 ** 32, (2 ** 32 + .2345)

tests += 1.2345, 1.2, 0.2345

tests += −1.2345, −1.2, −0.2345

tests += −(2 ** 32), −(2**32 + .2345)

tests += (2 ** 100), −(2 ** 100)

for test in tests:

print('%s [%s]' % (money(test, 17), test))

import sys

if len(sys.argv) == 1:

selftest()

else:

print(money(float(sys.argv[1]), int(sys.argv[2])))

This file works the same in Python 2.6 and 3.0. When run directly, it tests itself as before, but it uses options on the command line to control the test behavior. Run this file directly with no command-line arguments on your own to see what its self-test code prints. To test specific strings, pass them in on the command line along with a minimum field width:

C:\misc> python formats.py 999999999 0

$999,999,999.00

C:\misc> python formats.py −999999999 0

$-999,999,999.00

C:\misc> python formats.py 123456789012345 0

$123,456,789,012,345.00

C:\misc> python formats.py −123456789012345 25

$ −123,456,789,012,345.00

C:\misc> python formats.py 123.456 0

$123.46

C:\misc> python formats.py −123.454 0

$-123.45

C:\misc> python formats.py

...canned tests: try this yourself...

As before, because this code is instrumented for dual-mode usage, we can also import its tools normally in other contexts as library components:

>>> from formats

Return Main Page Previous Page Next Page

®Online Book Reader