Python中适当的方法在设置变量时引发错误

时间:2010-03-26 18:45:02

标签: python error-handling

在课堂上进行错误检查的正确方法是什么?提出例外?设置包含所有错误并返回错误的实例变量字典“errors”?

从班级打印错误是不是很糟糕? 如果我提出异常,我是否必须返回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()

3 个答案:

答案 0 :(得分:40)

您的代码不在上下文中,因此不是明显的正确选择。以下提示:

  • 不要使用NameError异常,只有在本地或全局范围内找不到名称(如异常本身所述)时才使用它,使用ValueError或{{ 1}}如果异常涉及参数的值或类型;

  • 不要打印错误消息。使用有意义的错误消息提出有意义的异常:

    TypeError
  • 从setter返回一个值是没有意义的,而赋值不是表达式,即你不能检查赋值的值:

    raise ValueError("password must be longer than 6 characters")
    
  • 只需在setter中引发异常,让设置属性的代码处理它。

示例:

if (user.password = 'short'): ...

另请参阅this forms handling library,验证器here an example是自己的实体:它们可以使用更高的控制和更少的耦合代码动态设置,但这可能远远超过您的需要

答案 1 :(得分:10)

在python中发出错误信号的标准方法是引发异常并让调用代码处理它。让NameError&amp; TypeError继续向上,或捕获它们并引发您定义的InvalidPassword异常。

虽然可以像您一样从函数返回成功/失败标志或错误代码,但不建议这样做 - 调用者很容易忘记检查返回值并且错误丢失。除了你从属性设置器返回一个值 - 这在Python中是没有意义的,因为赋值不是表达式而不能返回值。

您也不应该在异常处理中为用户打印消息 - 如果您以后想要在GUI程序中使用该函数或类,该怎么办?在这种情况下,您的print语句无处可打印。将错误记录到日志文件(使用Python的日志记录模块)通常有助于调试。

答案 2 :(得分:4)

通常,您应指出使用异常传播的错误。如果您通过刚刚检查的内容发现错误,并且可以立即处理,则无需引发异常。

在setter的特定情况下,例如,返回False或其他任何内容都无济于事。设置你必须检查的实例变量是非常不理想的,因为那时你可能会错过事故错误。

print通常不是对错误的良好回应。在这种情况下,听起来你想告诉最终用户他们需要使用不同的密码。听起来你应该调用一种方法,使得带有表单的网页向用户解释出错了什么;你可以调用在你的类中执行该操作的方法,或者引发一个异常,该异常将传播并最终被捕获并用于此目的。 (这是一般性的建议。我不太了解Pylons告诉你它是怎么想你这样做的。)

您不应该提出自己的NameError例外情况。 NameError几乎总是表明你的程序中有拼写错误,因此你通常不想抓住它。通过捕捉它,你会在程序中引入不必要的不​​确定性。看起来它可能更像ValueError或其子类(class InvalidPasswordError(ValueError): pass)。

我不明白为什么要检查TypeError。您应该始终了解导致异常的原因。如果你在这种情况下这样做,那很好;我无法弄清楚通过提示用户你可以通过哪种错误引起的TypeError错误。

您以明文方式接收密码并存储其md5哈希的技术不是很安全。你应该研究像AuthKit这样可以使这个过程更加安全和抽象的东西。