Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most Pythonic way to do input validation [duplicate]

What is the most "correct", Pythonic way to do user input validation in Python?

I've been using the following:

while True:
    stuff = input("Please enter foo: ")
    try:
        some_test(stuff)
        print("Thanks.")
        break
    except SomeException:
        print("Invalid input.")

Which is nice and readable, I suppose, but I can't help wondering if there isn't some built-in function or something I should be using instead.

like image 644
henrebotha Avatar asked Dec 12 '13 09:12

henrebotha


2 Answers

I like decorators to separate the checking from the rest of the input handling.

#!/usr/bin/env python

def repeatOnError(*exceptions):
  def checking(function):
    def checked(*args, **kwargs):
      while True:
        try:
          result = function(*args, **kwargs)
        except exceptions as problem:
          print "There was a problem with the input:"
          print problem.__class__.__name__
          print problem
          print "Please repeat!"
        else: 
          return result
    return checked
  return checking

@repeatOnError(ValueError)
def getNumberOfIterations():
  return int(raw_input("Please enter the number of iterations: "))

iterationCounter = getNumberOfIterations()
print "You have chosen", iterationCounter, "iterations."

EDIT:

A decorator is more or less a wrapper for an existing function (or method). It takes the existing function (denoted below its @decorator directive) and returns a "replacement" for it. This replacement in our case calls the original function in a loop and catches any exception happening while doing so. If no exception happens, it just returns the result of the original function.

like image 139
Alfe Avatar answered Oct 26 '22 13:10

Alfe


The most Pythonic way to do this kind of validation of "User INput" is to catch an appropriate exception.

Example:

def get_user_input():
    while True:
        try:
            return int(input("Please enter a number: "))
        except ValueError:
            print("Invalid input. Please try again!")

n = get_user_input()
print("Thanks! You entered: {0:d}".format(n))

It's also good practice to allow exceptions occur where they lie and allow them to bubble up rather than hide them so you can clearly see what's going wrong in a Python Traceback.

In this case Validating User Input -- Use Python's Duck Typing and catch the error. i.e: If it acts like a duct, it must be a duck. (If it acts like an int, it must be an int).

like image 28
James Mills Avatar answered Oct 26 '22 13:10

James Mills