2015-02-17 2 views
0

Я пишу небольшую функцию, которая принимает целое значение и строки, такие как:Pythonic способ справиться проверки

param1: 1 
param2: "1 1 1" 

Функция разделит строковый параметр и подтвердить его Len против первого параметра, как так:

def prepare_integer_set(expected_len, integer_string): 
    prepared_integer_set = integer_string.split() 
    if len(prepared_integer_set) != expected_len: 
     raise ValueError('Number of expected integers does not match integer string') 
    return [int(x) for x in prepared_integer_set] 

Однако исключение беспокоит меня. Я предпочел бы вернуть false, поскольку вход поступает от пользователя, поэтому это не исключение, если они делают ошибку.

Как это следует обрабатывать? Разделить метод в 2, имея отдельные методы проверки и подготовки? Или это pythonic, поскольку в настоящее время он выбрасывает исключение?

Здесь будет альтернатива, которая расщепляется:

def validate_integer_set(expected_len, integer_set): 
    return expected_len == len(integer_set) 


def prepare_integer_set(integer_string): 
    prepared_integer_set = integer_string.split() 
    return [int(x) for x in prepared_integer_set] 
+2

Если вы хотите вернуть False, почему бы не просто вернуть False? –

+1

Потому что я буду возвращать смешанные типы –

+0

Итак? Это не обязательно плохо ... Это зависит от того, что делает эта функция (в контексте приложения) и где она это делает ... – Carpetsmoker

ответ

2

Вы должны решить, что prepare_integer_set() делает:

  • Если только проверки пользовательского ввода, он должен вернуть True или False. Если он возвращает True, вы обрабатываете данные как обычно.
  • Если это что-то делает с данными, то неверные данные должны привести к исключению.
  • Вы можете в качестве альтернативы вернуть None или другое значение ложности, но будьте осторожны. Если ваше нормальное возвращаемое значение также может быть ложным (например, пустой список), это может вызвать больше проблем, чем это стоит.
+0

пустой список невозможен, если пройден тест длины –

+0

@PadraicCunningham: 'param1 = 0' и' param2 = '' '. '.split()' вернет пустой список. – Kevin

+0

0 пустая строка сделает функцию довольно избыточной. –

0

Я хотел бы вернуться Ложные, если вы не хотите, чтобы вызвать ошибку, то используйте простой, если проверка позже, прежде чем продолжить:

def prepare_integer_set(expected_len, integer_string): 
    prepared_integer_set = integer_string.split() 
    # catch 0 and negative input 
    if len(prepared_integer_set) != expected_len or expected_len < 1: 
     return False 
    return [int(x) for x in prepared_integer_set] 

val = prepare_integer_set(2,"1 2") 
if val: # if length test failed it will evaluate to False else we have a list of ints which will evaluate to True 
    ... 

Вы также должны учитывать вклад как, prepare_integer_set(3,"1 2 foo"), который будет проходить ваш текущий тест длины, но не работает при литье. Поэтому вы можете снова использовать try/except, возвращая False.

def prepare_integer_set(expected_len, integer_string): 
    prepared_integer_set = integer_string.split() 
    if len(prepared_integer_set) != expected_len or expected_len < 1: 
     return False 
    try: 
     return [int(x) for x in prepared_integer_set] 
    except ValueError: 
     return False 

Если вы не считаете неправильную длину, ошибка то вход, который не может быть приведен к междунар, вероятно, следует относиться так же, или оба должны рассматриваться как ошибка и исключение поднятый вместо возвращения Ложные , На самом деле то, что вы делаете с возвращаемым значением, должно диктовать, нужно ли поднимать ошибку или возвращать False для плохого ввода, я не думаю, что делать разные вещи для обеих ситуаций - хорошая идея.

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