进行输入验证的大多数Python方法



在Python中进行用户输入验证的最"正确"的Python方法是什么?

我一直在使用以下内容:

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

我想这很好,可读性很强,但我忍不住想知道是否有一些内置功能或我应该使用的东西。

我喜欢decorator将检查与其他输入处理分开。

#!/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."

编辑:

装饰器或多或少是现有函数(或方法)的包装器。它接受现有函数(在其@decorator指令下面表示),并为其返回一个"替换"。在我们的例子中,这个替换在循环中调用原始函数,并捕获在执行过程中发生的任何异常。如果没有发生异常,它只返回原始函数的结果。

对"用户输入"进行这种验证的最简单的Python方法是捕获适当的异常。

示例:

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))

允许异常发生在它们所在的地方,并允许它们冒泡而不是隐藏它们,这样您就可以清楚地看到Python Traceback中出现了什么问题,这也是一种很好的做法。

在这种情况下,验证用户输入--使用Python的Duck Typeing并捕获错误。如果它的行为像一个管道,那它一定是一只鸭子。(如果它的行为类似于int,则它必须是int)。

有点复杂,但可能很有趣:

import re
from sys import exc_info,excepthook
from traceback import format_exc
def condition1(stuff):
    '''
    stuff must be the string of an integer'''
    try:
        i = int(stuff)
        return True
    except:
        return False
def condition2(stuff):
    '''
    stuff is the string of an integer
    but the integer must be in the range(10,30)'''
    return int(stuff) in xrange(10,30)
regx = re.compile('assert *( *([_a-zd]+)')
                  
while True:
    try:
        stuff = raw_input("Please enter foo: ")
        assert(condition1(stuff))
        assert (  condition2(stuff))
        print("Thanks.")
        break
    except AssertionError:
        tbs = format_exc(exc_info()[0])
        funky = globals()[regx.search(tbs).group(1)]
        excepthook(exc_info()[0], funky.func_doc, None)

结果

Please enter foo: g
AssertionError: 
    stuff must be the string of an integer
Please enter foo: 170
AssertionError: 
    stuff is the string of an integer
    but the integer must be in the range(10,30)
Please enter foo: 15
Thanks.

编辑

我找到了一种简化的方法:

from sys import excepthook
def condition1(stuff):
    '''
    stuff must be the string of an integer'''
    try:
        int(stuff)
        return True
    except:
        return False
def another2(stuff):
    '''
    stuff is the string of an integer
    but the integer must be in the range(10,30)'''
    return int(stuff) in xrange(10,30)
tup = (condition1,another2)
while True:
    try:
        stuff = raw_input("Please enter foo: ")
        for condition in tup:
            assert(condition(stuff))
        print("Thanks.")
        break
    except AssertionError:
        excepthook('AssertionError', condition.func_doc, None)

相关内容

  • 没有找到相关文章

最新更新