Описание :

Я прочитал много мнений о проверке типа значения в Python, и большинство из них сказали, что вам не следует проверять тип, а вместо этого использовать try и исключением. Я хочу прояснить несколько вещей.

Вопросы :

Когда у меня есть такой метод:

def set_age(self, age):
    self._age = age

Я не могу позволить пользователю передавать любые типы, кроме int, потому что позже в коде это может привести к более трудным отладкам ошибок. И согласно методологии Python я не могу проверить тип. Так как я должен сделать это с попыткой надлежащим образом?

def set_age(self, age):
    try:
        age = int(age)
    except TypeError:
        raise TypeError('First parameter must be of int type.')
    self._age = age

Или просто

def set_age(self, age):
    self._age = int(age)

И пусть Python самостоятельно поднимает ошибки.

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

2
Rafał Łużyński 26 Янв 2013 в 18:39

2 ответа

Лучший ответ

Python выдаст соответствующую ошибку, если она не является целым числом, поэтому нет необходимости помещать свою собственную поверх нее.

Давайте вернемся немного назад, поскольку здесь есть другие проблемы. методы получения и установки действительно непифоновы - либо просто используйте атрибут, либо используйте свойства .

В этом случае, я думаю, вы все еще думаете неправильно. Причина, по которой мы не проверяем тип в Python, заключается в том, что нам не важно, что это за тип, если он будет работать в данной ситуации. Делать все так, как вы думаете, должно быть, как только вы его получите, по сути, это проверка типов.

Вы говорите, что будет труднее отлаживать, но на самом деле это не тот опыт, который есть у большинства людей. Утиная печать предназначена для того, чтобы все, что может сделать работу, выполняло свою работу. Преобразование всего в int ограничивает вашу программу. Проблема не в этом, проблема в том, что ваш код передает то, что не имеет смысла для вашего класса. По моему опыту, это на самом деле очень редкая вещь - вы не склонны бросать случайные вещи в классы и смотреть, что прилипает.

Итак, мое предложение здесь заключается в том, что вы используете атрибут - просто сделайте x.age = ... вместо использования set_age() или что-то в этом роде. Если вам действительно нужно иметь int (как, впрочем, смысл имеют только целые числа), тогда используйте свойство и вызовите int() в установщике, оставляя ошибку для распространения звонящему, если это произойдет.

2
Gareth Latty 26 Янв 2013 в 14:46

Один из принципов Python: «Лучше просить прощения, чем разрешения». Много раз исключений, сгенерированных функциями, которые вы вызываете из функций, достаточно, чтобы сообщить вызывающей стороне вашей функции, что пошло не так.

При этом в некоторых случаях я выброшу более конкретное исключение, когда семантика для вызывающей стороны не полностью совпадает. Один пример, который я могу вспомнить, - это когда я изучаю ответ json и получаю «ключевую ошибку» в одном элементе словаря. Обычно это означает, что любой запрос, который я отправил, потерпел неудачу, и поэтому я не могу найти нужные мне данные. Я, в свою очередь, добавлю что-то более семантически в соответствии с моей функцией, такой как «Query Failed».

Однако в большинстве случаев исключения, вызываемые вызываемыми функциями «ошибка типа» или «ошибка ввода-вывода», должны иметь смысл для вызывающей стороны моей функции, поэтому я не беспокоюсь о перехвате и перебрасывании.

1
Doug T. 26 Янв 2013 в 14:43