Правильный путь в Python для повышения ошибок при настройке переменных
Каков правильный способ проверки ошибок в классе? Исключение исключений? Установка словаря переменных переменных "ошибки", содержащего все ошибки и возвращающие его?
Плохо ли печатать ошибки из класса?
Должен ли я возвращать False, если я создаю исключение?
Просто хочу убедиться, что я делаю все правильно. Ниже приведен пример кода:
@property
def password(self):
return self._password
@password.setter
def password(self,password):
# Check that password has been completed
try:
# Check that password has a length of 6 characters
if (len(password) < 6):
raise NameError('Your password must be greater \
than 6 characters')
except NameError:
print 'Please choose a password'
return False
except TypeError:
print 'Please choose a password'
return False
#Set the password
self._password = password
#Encrypt the password
password_md5 = md5.new()
password_md5.update(password)
self._password_md5 = password_md5.hexdigest()
Ответы
Ответ 1
Ваш код выходит из контекста, поэтому нет очевидного правильного выбора. Следуя советам:
-
Не используйте исключение NameError
, оно используется только тогда, когда имя, как сказано выше, не найдено в локальной или глобальной области, используйте ValueError
или TypeError
, если исключение относится к значению или типу параметра;
-
Не печатайте сообщения об ошибках. Поднимите значимые исключения со значимым сообщением об ошибке:
raise ValueError("password must be longer than 6 characters")
-
Возвращение значения из сеттера бессмысленно, в то время как присвоение не является выражением, т.е. вы не можете проверить значение присваивания:
if (user.password = 'short'): ...
-
Просто поднимите исключение в установщике и пусть код, который устанавливает свойство, обрабатывает его.
Пример:
class Test:
minlen = 6
@property
def password(self):
return self._password
@password.setter
def password(self, value):
if not isinstance(value, basestring):
raise TypeError("password must be a string")
if len(value) < self.minlen:
raise ValueError("password must be at least %d character len" % \
self.minlen)
self._password = value
Посмотрите также на эту библиотеку обработки форм, там валидаторы, здесь пример, являются собственными объектами: они могут быть установлены динамически с более высоким контролем и менее связанным кодом, но, возможно, это намного больше, чем вам нужно.
Ответ 2
Стандартный способ сообщения об ошибке в python - это создать исключение и позволить коду вызова обрабатывать его. Либо пусть NameError и TypeError переносятся вверх, либо ловят их и создают исключение InvalidPassword, которое вы определяете.
Хотя можно вернуть флаг успеха/ошибки или код ошибки из функции, как вы это сделали, это не рекомендуется - пользователю легко забыть проверить возвращаемое значение и потерять ошибки. Кроме того, вы возвращаете значение из средства настройки свойств - это не имеет смысла в Python, поскольку назначения не являются выражениями и не могут вернуть значение.
Вы также никогда не должны печатать сообщение для пользователя в вашей обработке исключений - что, если вы позже захотите использовать функцию или класс в программе GUI? В этом случае вашему заявлению на печать некуда будет печатать. Однако регистрация сообщения об ошибке в файле журнала (с использованием модуля протоколов Python) часто бывает полезной для отладки.
Ответ 3
Как правило, вы должны указывать ошибки, которые распространяются с использованием исключений. Если вы обнаружили ошибку, которую вы только что отметили, и вы можете сразу ее решить, нет необходимости поднимать исключение.
В частном случае сеттера, например, возвращение False
или что-то еще не поможет. Установка переменных экземпляра, которые вы должны проверить, очень субоптимальна, так как тогда вы можете пропустить ошибку при аварии.
print
обычно не является хорошим ответом на ошибку. В этом случае, похоже, вы хотите сообщить конечному пользователю, что им нужно использовать другой пароль. Похоже, вы должны вызвать метод, который заставляет веб-страницу с формой объяснять пользователю, что пошло не так; вы можете вызвать метод, который делает это в вашем классе, или создать исключение, которое будет распространяться и в конечном итоге быть пойманным и использованным для этой цели. (Это общий совет. Я не знаю достаточно о Пилонах, чтобы рассказать вам, как он хочет, чтобы вы это делали.)
Вы не должны создавать свои собственные исключения NameError
. NameError
prettymuch всегда указывает опечатку в вашей программе, и поэтому вы обычно не хотите ее ловить. Ловя его, вы вводите ненужную неопределенность в программу. Похоже, что это может быть чем-то вроде ValueError
или его подкласса (class InvalidPasswordError(ValueError): pass
).
Я не понимаю, почему вы проверяете TypeError
. Вы всегда должны понимать, что вызвало бы исключение, которое вы поймали. Если вы сделаете это в этом случае, это здорово; Я не могу понять, какая ошибка поднимет TypeError
, с которой вы могли бы разумно справиться, предложив пользователю.
Ваша методика получения пароля в открытом виде и хранения его хэша md5 не очень безопасна. Вы должны изучить нечто вроде AuthKit, которое могло бы сделать этот процесс более безопасным и абстрагированным.