2013-07-17 2 views
0

У меня есть графический интерфейс, где я прошу пользователя ввести некоторые значения. Когда пользователь отправляет данные мне сделать некоторые проверки:Подробнее pythonic способ проверить, существует ли пользовательский ввод и состоит из целых чисел

  1. первым проверить, если пользователь ввел значение для каждого входа
  2. затем проверить, если каждый из введенных значений целых числа

Пытаясь не повторять себя, я придумал это, но вторая часть проверки больше похожа на хак. Есть ли более питонический способ переписать это, не говоря о том, что все, как в первой части проверки?

errors = [] 
    # 1) check if values exist 
    if not self.startInput.GetValue(): 
     errors.append("Please provide a start") 
    if not self.stopInput.GetValue(): 
     errors.append("Please provide a stop") 
    if not self.valueInput.GetValue(): 
     errors.append("Please provide a value") 
    # 2) check if values are integers 
    try: 
     self.start = int(self.startInput.GetValue()) 
     self.stop = int(self.stopInput.GetValue()) 
     self.value = int(self.valueInput.GetValue()) 
    except ValueError as err: 
     tb = traceback.format_exc() 
     func = re.search('self\.(.*) =', tb).groups()[0] 
     errors.append("Value for {0} needs to be an integer.".format(func)) 
    if errors: 
     raise RuntimeError('\n'.join(errors)) 

ответ

4

Поскольку вы проверяете для целых чисел, а не поплавками, вы можете просто сделать:

if self.start.GetValue().strip().isdigit(): 
    pass 

isdigit() возвращается False для обоих случаев, когда вход является пустая строка, и, когда вход содержит без цифр.

Если вы хотите, чтобы передать определенные ошибки за неправильное назначение:

startValue = self.start.GetValue().strip() 

if not startValue: 
    errors.append("Please provide a start.") 

if not startValue.isdigit(): 
    errors.append("Value of start must be an integer.") 
+0

Это кажется хорошим вариантом, но тогда у меня нет способа давать разные сообщения об ошибках на основе отсутствия данных («Укажите начальное значение») по сравнению с данными, но не является целым числом (" Значение для начала должно быть целым числом "). Верный? – BioGeek

+0

@BioGeek: Верно, если вы хотите эту функциональность, я бы пошел либо с двумя операциями 'if', либо с блоком' try ... except'. Любой из них является совершенно питоническим. –

+0

@BioGeek См. Мое редактирование. –

1

Я думаю, что try: ... except совершенно Pythonic. Я бы использует вспомогательную функцию вместо поиска через сообщение об ошибке get_int_of_name(name, value, error), который возвращает ошибку Int и обновления, если это необходимо:

def get_int_of_name(name, value, error): 
    try: 
     res = int(value) 
    except ValueError: 
     error.append("...") 
     return 0 
    else: 
     return res 
+1

Я согласен, что 'try ... except' является красиво явным и, следовательно, pythonic. Однако вам следует избегать ловить голых исключений. Я бы выполнил 'except ValueError:' вместо 'except:'. –

+0

@Joel: Это более синтаксический анализ с регулярным выражением трассировки, когда есть «ValueError», который казался мне неприличным. – BioGeek

+1

@ Джоэль Корнетт: Конечно! Я проверял, какое исключение я хотел поставить здесь, и забыл поставить правильный. Я исправил это сейчас. – hivert

1

Если у вас есть эти входы в словаре называется inputs вы можете сделать:

errors = [] 
for inputname, inputval in self.inputs.items(): 
    if not inputval: 
     errors.append("Please provide a {}".format(inputname)) 
    try: 
     setattr(self, inputname, int(inputval.GetValue())) 
    except: 
     errors.append("Value for {0} needs to be an integer.".format(inputname)) 
if errors: 
    raise RuntimeError('\n'.join(errors)) 
+1

+1 для включения _all_ неверно отформатированных значений в список ошибок, а не только первый – Henrik

Смежные вопросы