我正在尝试使用Python验证简单字段的输入。
我在SO上尝试过很多建议。我的代码:
class Map(object):
def __init__(self):
# Note: These are defaults.
# map_x and map_y both have a range of 20 <= x <= 100
# obstacles = 'Y' || 'N'
self.map_x = -1
self.map_y = -1
self.obstacles = '-'
def forest_map(self):
self.map_x = self.choice("Map Width")
self.map_y = self.choice("Map Length")
self.obstacles = self.choice("Obstacles (Y/N)")
def choice(self, text):
# Code
为了坚持“高效”和“可重用”代码的概念,我尝试了几种不同的解决方案。
在方法“选择”中找到文本参数的原因:我已经提示指示用户正在与之交互的内容(例如,choice = raw_input(text +“ - &gt;”))。
我的解决方案:
我已尝试使用if语句对text参数进行测试,但对我而言,这对于此解决方案来说太特殊了;因此,不可重复使用。
我尝试过使用try / except,但是,即便如此,我的while语句似乎正在消耗输入,并且没有向map_x和map_y返回值。
我已经尝试过(使用字典成功地在上一部分中选择菜单而不是收集用户首选项),如下所示:
# menu is an argument that takes a dictionary.
# dictionary can be found in a list of dictionaries named menu_list.
# choice is a member of class Menus, and menu_list is defined in Menu's __init__.
def choice(self, menu):
acceptable = menu
if menu == self.menu_list[2]:
choice = raw_input("Choice-> ")
while choice not in acceptable:
choice = raw_input("Choice-> ")
Map().generate(choice)
我只是成功地测试了“障碍”。我用过(虽然选择不在['Y','y','N','n']:#Code
截至目前,我只是在测试整数方面存在问题,同时要坚持可重用性和效率方面。
有没有办法可以看到输入(选项)是否包含任何类型的字母,因此请求更多输入? 有没有办法同时确保map_x / map_y在2&lt; = choice&lt; = 100?
的范围内非常感谢, Akratix
===编辑10/2/14 === 由于下面的解决方案,我已经提出了两个实现。 为了验证应该是整数以及在设定范围内的输入,我使用以下代码片段:
def map_choice(self, text):
is_valid = False
while not is_valid:
try:
value = int(raw_input(text + "-> "))
if 2 > value or 100 < value:
print "Invalid input!"
continue
return value
except ValueError:
print "Invalid input!"
为了验证在可接受输入的“列表”中应该是特定字母的输入,我使用以下代码片段:
def obstacle_choice(self, text):
is_valid = False
while not is_valid:
value = raw_input(text + "-> ")
if any(value == x for x in ('Y', 'N', 'y', 'n')):
return value
答案 0 :(得分:0)
你有一个良好的开端,但不要过分试图概括一切。您有两个截然不同的字段,具有不同的验证,因此使用两个不同的“选择”函数是有意义的。
使用以下内容会更简单。您甚至可以自定义字段错误消息,告诉用户他的输入无效,并且通常会更有帮助。
def forest_map(self):
self.map_x = self.map_choice("Map Width")
self.map_y = self.map_choice("Map Length")
self.obstacles = self.obstacle_choice("Obstacles (Y/N)")
def map_choice(self, message)
# here we use try except to make sure its an integer
try:
value = int(raw_input(message))
except ValueError:
print "Invalid input!"
return -1
# check range
if 20 > value or 100 < value:
print "Invalid input!"
return -1
return value
def obstacle_choice(self, message):
value = raw_input(message)
# check if its an acceptable answer
if any( value == x for x in ('Y', 'N', 'y', 'n') ):
return value
print "Invalid input!"
return -1
或者,如果你有很多字段,那么有一个选择函数将验证函数作为参数可能是值得的。与您的第二个choice
函数类似,但我们不是采用“菜单”字典,而是采用验证函数。
def forest_map(self):
valid_map = lambda x: 20 <= int(x) <= 100
valid_obstacle = lambda x: any( x == y for y in ('Y', 'N', 'y', 'n') )
# the choice function will guarantee its safe to use int on the result
self.map_x = int(self.choice("Map Width", valid_map))
self.map_y = int(self.choice("Map Length", valid_map))
self.obstacles = self.choice("Obstacles (Y/N)", valid_obstacle)
def choice(self, message, validate):
"""
Prompt a user for input and validate the input
Args:
message (str): Message to display at prompt
validate (callable): callable of one parameter to validate input
Returns:
str: A valid user input
"""
is_valid = False
while not is_valid:
# prompt for input
value = raw_input(message)
# validate input with our validation function
# if validate(value) returns True, it ends the loop
try:
is_valid = validate(value)
# maybe the validation function throws an exception
# its best to catch the specific error class, but I'll use Exception for simplicity
except Exception:
is_valid = False
return True
最后,关于检查输入是否包含任何字母。您可以使用isalpha
方法检查字符串中的每个字符是否都是字母。要检查字符串中的任何字符是否为字母,您可以使用此字符。
value = raw_input('>')
contains_letters = any( c.isalpha() for c in value )
答案 1 :(得分:0)
为choice
函数添加一个额外的参数,我通常将其称为type
(尽管与内置函数发生冲突),这是一个可调用的函数,可以转换并验证参数。
使用此示例,例如IntRange(2, 100)
class IntRange(object):
def __init__(self, min, max):
self.min = min
self.max = max
def __call__(self, s):
i = int(s) # throws
if self.min <= i <= self.max:
return i
raise ValueError('%d is out of range' % i)
我已实施的更多类型:https://github.com/o11c/attoconf/blob/master/attoconf/types.py; enum
类型可能对y / n答案有用(但您可能也需要一些可以进行大小写规范化的方法)