Python中设置变量时引发错误的正确方法

Python中设置变量时引发错误的正确方法,python,error-handling,Python,Error Handling,在类中进行错误检查的正确方法是什么?提出例外?设置包含所有错误的实例变量字典“errors”并返回它 打印类中的错误是否不好? 如果引发异常,是否必须返回False 只是想确保我做的事情是正确的。下面是一些示例代码: @property def password(self): return self._password @password.setter def password(self,password): # Check that password has been com

在类中进行错误检查的正确方法是什么?提出例外?设置包含所有错误的实例变量字典“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()
@属性
def密码(自我):
返回self.\u密码
@密码设置器
def密码(self,password):
#检查密码是否已完成
尝试:
#检查密码的长度是否为6个字符
如果(len(密码)<6):
raise NAME ERROR('您的密码必须更大\
超过6个字符)
除名称错误外:
打印“请选择密码”
返回错误
除类型错误外:
打印“请选择密码”
返回错误
#设置密码
self.\u password=密码
#加密密码
密码\u md5=md5.new()
密码\u md5.更新(密码)
self.\u password\u md5=password\u md5.hexdigest()

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

虽然可以像您所做的那样从函数中返回成功/失败标志或错误代码,但不建议这样做-调用者很容易忘记检查返回值并丢失错误。此外,您正在从属性设置器返回值——这在Python中毫无意义,因为赋值不是表达式,不能返回值


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

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

例如,在setter的特定情况下,返回
False
或其他任何内容都没有帮助。设置您必须检查的实例变量是非常不理想的,因为这样您可能会错过一个意外错误

打印
通常不是对错误的良好响应。在这种情况下,听起来您想告诉最终用户他们需要使用不同的密码。听起来您应该调用一个方法,使带有表单的网页向用户解释出错的原因;您可以在类中调用执行该操作的方法,或者引发一个异常,该异常将传播并最终被捕获并用于该目的。(这是一般性建议。我对塔架了解不够,无法告诉您它希望您如何做到这一点。)

您不应该提出自己的
namererror
异常
NameError
prettymuch始终表示程序中存在键入错误,因此您通常不想捕捉它。通过捕捉它,您会在程序中引入不必要的不确定性。这看起来可能更像
ValueError
或其子类(
类InvalidPasswordError(ValueError):pass

我不明白你为什么要检查
TypeError
。您应该始终了解是什么导致您捕获的异常。如果你在这种情况下这样做,那就太好了;我不知道什么错误会引起
TypeError
,您可以通过提示用户来理智地处理


以明文形式接收密码并存储其md5哈希的技术不是很安全。您应该研究类似AuthKit的东西,以使此过程更加安全和抽象。

您的代码脱离上下文,因此显然不是正确的选择。以下是一些提示:

  • 不要使用
    namererror
    exception,它仅在本地或全局范围内找不到名称时使用,如果异常涉及参数的值或类型,请使用
    ValueError
    TypeError

  • 不要打印错误消息。引发有意义的异常,并显示有意义的错误消息:

    raise ValueError("password must be longer than 6 characters")
    

  • 当赋值不是表达式时,从setter返回值是没有意义的,即不能检查赋值的值:

    if (user.password = 'short'): ...
    
  • 只需在setter中引发一个异常,并让设置属性的代码处理它

例如:

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
类测试:
minlen=6
@财产
def密码(自我):
返回self.\u密码
@密码设置器
def密码(自身,值):
如果不是isinstance(值、基串):
raise TypeError(“密码必须是字符串”)
如果len(值)

再看看验证器,它们有自己的实体:它们可以通过更高的控制和更少的代码耦合动态设置,但这可能比您需要的多得多。

在代码中有太多名为
密码的东西。(第一个函数、第二个函数和第二个函数的参数。)pyflakes将是您的朋友。@keturn:这是文档中显示的
property()
函数的模式。看这张照片。setter方法
password
中有一个局部变量(参数)。其他名称位于不同的命名空间中(它们属于该类)。@mg,很棒的帖子(还有很棒的首字母缩写!)