在Python中验证构造函数参数的最佳实践方法是什么?
我是该语言的新手,正在使用raise
:
class Breakfast(object):
def __init__(self, spam=None, eggs=0):
if not spam:
raise Error("Error: no spam")
这是愚蠢的,还是什么?
谢谢!
答案 0 :(得分:4)
如果您只是想确保传递所需的参数,请不要使用默认值。如果参数丢失,Python将自动抛出TypeError。
def __init__( self, spam, eggs=0 )
答案 1 :(得分:3)
如果参数不是可选的,为什么要为它提供默认参数?如果没有传递默认值的参数,Python解释器会自动引发错误。
答案 2 :(得分:3)
在您的具体示例中,不给spam
一个默认值是最简单的 - 如果用户忘记传递该参数,Python将为您诊断问题。 (但是,将False
,0
,[]
,...作为spam
传递给Python是可以的,因此如果您对它们有要求,则可能需要另外指定你自己的语义检查)。
如果您确实需要执行任何诊断,如果失败则引发异常是明智的。但是它应该是正确的例外 - 例如,ValueError
如果值是可接受的类型但不能作为其特定值接受 - 并且具有清晰,完整的消息。所以,总结一下:
class Breakfast(object):
def __init__(self, spam, eggs=0):
if not spam:
raise ValueError("falsish spam %r not acceptable" % (spam,))
(你需要在这里将spam
包装在单项元组(spam,)
中,否则将空元组作为spam
传递会导致复杂,混乱的错误;-)。
答案 3 :(得分:0)
在这种特殊情况下,请勿将垃圾邮件设为关键字:
class Breakfast(object):
def __init__(self, spam, eggs=0):
"""Spam may not be none.
"""
# This is just validation of parameters which you can either
# do or leave. spam is part of the contract now and you documented
# that it may not be None
if not spam:
raise Error("Error: spam may not be None")
答案 4 :(得分:0)
首先,我认为你的意思是
if spam is None:
Breakfast(0)
对not spam
的布尔为True,因为它是[]
,0.0
,''
,u''
等的参数
其次,引发的错误是一个无信息的泛型类,而不是更典型的ValueError
。最后,异常文本可以提供更多信息,并指导调用者进行修复。
并且,正如其他人所说,你通过设置没有默认值的默认值来牺牲自动检查。