Подтвердить что ты не робот

Правильный путь в 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()
4b9b3361

Ответ 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, которое могло бы сделать этот процесс более безопасным и абстрагированным.