Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
最具python风格的输入验证方法_Python_Validation_User Input_Assert - Fatal编程技术网

最具python风格的输入验证方法

最具python风格的输入验证方法,python,validation,user-input,assert,Python,Validation,User Input,Assert,用Python进行用户输入验证的最“正确”的Python方式是什么 我一直在使用以下方法: while True: stuff = input("Please enter foo: ") try: some_test(stuff) print("Thanks.") break except SomeException: print("Invalid input.") 我想这很好,可读性也很好,但我不禁想知道

用Python进行用户输入验证的最“正确”的Python方式是什么

我一直在使用以下方法:

while True:
    stuff = input("Please enter foo: ")
    try:
        some_test(stuff)
        print("Thanks.")
        break
    except SomeException:
        print("Invalid input.")
我想这很好,可读性也很好,但我不禁想知道是否有一些内置函数或我应该使用的东西。

对“用户输入”进行此类验证的最具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回溯中的错误


在本例中,验证用户输入——使用Python的Duck键入并捕获错误。i、 e:如果它像管道,那一定是鸭子。(如果它的行为类似于int,那么它必须是int)。

我喜欢用装饰程序将检查与输入处理的其余部分分开

#!/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
指令下面表示),并为其返回一个“替换”。在我们的例子中,这个替换调用循环中的原始函数,并捕获执行此操作时发生的任何异常。如果没有发生异常,它只返回原始函数的结果。

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

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-z\d]+)')
                  
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)

你能再给我看一些代码吗?对不起,我在打字之前无意中提交了!我认为你所做的(使用try~except)还不错,尽管有其他方法可以完成同样的任务。我没听说过“蟒蛇式”的方式。。这类任务在所有其他语言中都会发生。发布
some_test
函数,具体取决于您所说的“输入验证”(信用卡号、IP地址、int、float?)的含义,以及发生验证失败时您想做什么。换句话说,就是我在做什么。:)谢谢Jamesprecilly:)我只是觉得我应该扩展一下,谈谈“Pythonic方式”和原因:)这也很好,而且更进一步,有助于将其推广一点。Python decorators是一个非常强大的工具,可以让您以一种很好的方式编写函数。@Alfe:非常感谢您的回答。然而,尽管我在谷歌上热情洋溢,但我对装饰师的工作方式一无所知,所以我恐怕不太明白你的答案(我为代码添加了一个小的解释,但是当然,在这里解释decorators超出了范围。关于Stackoverflow这个主题有很多问题。谢谢。我现在对它有点了解了。确实很有趣,但对于日常任务来说,我想这非常复杂。我必须以一种有点可怕的方式下面查找其结果导致断言错误的函数:将回溯对象转换为字符串,在此字符串中搜索regex,将组传递给glabals以查找函数对象,获取函数的文档!我没有成功地直接从回溯对象提取函数或其名称。-但是基本idea可能很有趣:可以简单地添加条件函数,而无需更改except块。@henrebotha我得到了一个很强的简化