Lesson 5 - I/O

Avram Lubkin
Rockhopper Technologies

Command Line Arguments

  • To obtain command line arguments for a Python script use sys.argv

  • sys.argv is a list where sys.argv[0] is the script name

    #!/usr/bin/env python
    
    import sys
    
    for argument in sys.argv:
        print(argument)
    
    $ ./test.py arg1 arg2 "string with spaces"
    ./test.py
    arg1
    arg2
    string with spaces
    

Advanced Command Line Arguments

  • To write Python scripts which take more complicated options, use the argparse module
    • argparse supports short (-o) or long (--option) options
    • Automatically generates help output
    • Checks for required arguments and mutually-exclusive arguments
    • Highly configurable
    import argparse
    parser = argparse.ArgumentParser(description='Best program, ever!')
    parser.add_argument('-n', '--number', metavar='NUMBER', type=int,
                        required=True, help='Number of times to shout')
    
    options = parser.parse_args()
    print('Shout! ' * options.number)
    

User Input

  • To get user input, use raw_input() (Python 2) or input() (Python 3)

  • Python 2

    name = raw_input("What is your name? ")
    print "Hi, %s" % name
    
  • Python 3

    name = input("What is your name? ")
    print("Hi, %s" % name)
    
  • Result

    What is your name? Avram
    Hi, Avram
    

User Input

  • For version-agnostic user input

    • Standard Library only

      import sys
      if sys.version_info[0] > 2:
          INPUT = input
      else:
          INPUT = raw_input
      
      name = INPUT("What is your name? ")
      
    • Using the six module

      from six.moves import input
      name = input("What is your name? ")
      

File I/O

  • Open a file with the open() function
    • Supports the following modes:
      • r – read (default)
      • w – write, truncates file
      • x – open for exclusive creation, fails if exists
      • a – append to end of a file if it exists
      • b – binary mode - read and write as bytes
      • t – text mode - read and write as strings (default)
      • + – read and write
    • Modes are combined, for example a+b would open a file in binary mode without truncation
    • returns a file object

File I/O - Close

  • It is important to make sure file are closed when you are finished with them

  • One method of doing this is a try-finally statement
    • Ensures a file is closed even if there is an issue
    fileObject = open('filename')
    try:
        pass # Do many fancy file things
    finally:
        fileObject.close()
    
  • In Python 2.5 and later, files can be opened using a with statement

  • The file will automatically be closed when the with statement completes

    with open('filename') as fileObject:
        pass # Do many fancy file things
    

File I/O - Read

  • Open a file in text mode and read contents as a single string

    >>> with open('/etc/redhat-release') as releaseFile:
    ...     releaseFile.read()
    ...
    'Fedora release 24 (Twenty Four)\n'
    
  • Open a file in text mode and read contents line by line

    >>> with open('/etc/group') as groupFile:
    ...     groupFile.readline()  # Read the first line
    ...     for line in groupFile:  # Read the rest of the lines
    ...         print(line.strip())
    ...
    'root:x:0:\n'
    bin:x:1:
    daemon:x:2:
    sys:x:3:
    

File I/O - Write

  • When writing to a file object, newline characters must be explicitly added

  • Open a file and write a series of random numbers

    >>> import random
    >>> randomGen = random.SystemRandom()
    >>> with open('/tmp/random', 'w') as randomFile:
    ...     for num in range(1, 100):
    ...             randomNum = randomGen.randint(0, 100000)
    ...             randomFile.write('%d\n' % randomNum)
    ...
    
    $ cat /tmp/random
    42380
    30569
    43790
    76564
    ...
    

File I/O - Combined

  • Open multiple files at once

    >>> with open('/etc/group') as groupFile, open('/tmp/group', 'w') as newFile:
    ...     for line in groupFile:
    ...             groupname = line.split(':')[0]
    ...             newFile.write('%s\n' % groupname)
    ...
    
  • NOTE:

    When using write() on the Python 3 console, a series of numbers will be printed to the screen. This is the number of bytes written.

Standard Streams

  • The sys module includes three special file objects
  • Write to stdout
    • Use instead of print() when Python <=2.5 must be supported
    >>> sys.stdout.write("Hello, from sunny standard out\n")
    Hello, from sunny standard out
    
  • Write to standard error

    >>> sys.stderr.write("Hello, from the cold depths of standard error\n")
    Hello, from the cold depths of standard error
    

Standard Streams

  • Read from standard in

    #!/usr/bin/env python
    
    import sys
    input = sys.stdin.readlines()
    input.sort()
    for line in input:
        sys.stdout.write(line.upper())
    
    $ cat /etc/group | ./capitalize.py
    ABRT:X:173:
    ADM:X:4:
    AUDIO:X:63:
    AVAHI-AUTOIPD:X:170:
    AVAHI:X:70:
    ...
    

Exiting

  • A Python script will exit with a returncode of 0 if no unhandled exceptions occur

  • To exit explicitly, use sys.exit()
    • No arguments or None, returncode is 0
    sys.exit()
    
    • If an integer is given, it will be used as the returncode
    sys.exit(11)
    
    • If another object type is given, it is printed using str to standard error
      • Returncode will be 1
    if not len(sys.argv) > 1:
        sys.exit("Where are your arguments?")