User Input

Indices and tables

Introduction

Python offers functionality to obtain input from the user, both at the command line and interactively during run-time.

Command Line Input

Python provides the command line arguments your program was called with, as a list of strings referenced by argv in the sys package.

The item argv[0] is special. It is one of the following:

  • The script name, if the interpreter was called with the script name.
  • The string, ‘-c’, if the interpreter was executed with the -c option.
  • The empty string, if the interpreter is running interactively.

To get access to argv , import the sys module.

For example, assuming I have the following code in a python file called my_program.py:

#!/usr/bin/python3

import sys

for idx, arg in enumerate(sys.argv):
    print("arg{}: {}".format(idx, arg))

And it is called as follows:

> ./my_program.py aa bb 99 100

It will output the following:

arg0: ./my_program.py
arg1: aa
arg2: bb
arg3: 99
arg4: 100

Tip

The argparse package is a far more powerful, flexible and standardized way to handle command line arguments. You should use that package for all but the simplest scripts instead of using sys.argv directly.

Interactive Input

You can request user input at run-time using using the function input():

input([prompt])

Prompts the user for input. Converts all input lines to strings without newlines and returns it to the caller. If provided, the prompt string is written to the standard output before asking for user input. Returns EOFError if EOF is read.

Tip

Pressing ctrl-c generates a KeyboardInterrupt exception. Pressing ctrl-d generates a EOFError exception.

For example, a simple request for user input might look like the following:

def get_input():
   user_input = input('Yes/No/Retry --> ')
   print("The user entered: " + user_input)

And when called:

>>> get_input()
Yes/No/Retry --> Yes
The user entered: Yes

However, this assumes a well behaved user enters only valid values. Don’t be fooled. That assumption almost never holds true.

A more complex request for user input that includes some conditioning and exception handling might look like the following:

def get_input():
    # Loop until:
    # 1) we get valid input that corresponds to an acceptable value, or,
    # 2) the user presses either ctrl-c or ctrl-d.
    while True:
        try:
            # Ask for decision
            user_input = input('Yes/No/Retry/Cancel: ')
        except (KeyboardInterrupt, EOFError):
            # Detected a special keyboard sequence
            user_input = "Cancel"
        finally:
            # Filter out invalid input from the user
            user_input = user_input.lower()
            acceptable_vals = ('yes', 'y',
                               'no', 'n',
                               'retry', 'r',
                               'cancel', 'c')
            if user_input in acceptable_vals:
                # Pass back only first character of user
                # input as that is all that is important
                # to key future processing decisions off of.
                user_input = user_input[0]
                break
            else:
                print("Invalid value entered. Try again.")
    return user_input

def process():
    response = get_input()
    if response == 'y':
        print("\nThe user said 'Yes'")
    elif response == 'n':
        print("\nThe user said 'No'")
    elif response == 'r':
        print("\nThe user said 'Retry'")
    else:
        print("\nThe user said 'Cancel'")

When run, it responds to the items in the prompt:

>>> #
>>> # Enter a string response
>>> process()
Yes/No/Retry/Cancel: Yes
The user said 'Yes
>>> #
>>> # Enter an invalid value
>>> process()
Yes/No/Retry/Cancel: Quit
Invalid value entered. Try again.
Yes/No/Retry/Cancel:
>>> #
>>> # Enter ctrl-c or ctrl-d
>>> process()
Yes/No/Retry/Cancel:
The user said 'Cancel'

To accept a multi-line response from the user, you can read from standard input directly. For example:

import sys
def get_multiline_input():
    input_lines = ''
    try:
        print("Your answer --> ", end='')
        sys.stdout.flush()
        input_lines = sys.stdin.read()
    except KeyboardInterrupt:
        # User cancelled.
        pass
    finally:
        return input_lines

When run, it accepts multiple lines and returns them separated by new-lines (\n) characters:

>>> resp = get_multiline_input()
Your answer --> line 1
line 2
line 3
>>> resp
'line 1\nline 2\nline 3\n'

Note

When reading from stdin, the ctrl-d sequence from the user is required in order to send the data to stdin. Therefore it does not produce an EOFError like it does when using the input() function.