What is the best-practice method for verifying constructor params in Python?
I am new to the langu开发者_StackOverflowage, and am using raise
:
class Breakfast(object):
def __init__(self, spam=None, eggs=0):
if not spam:
raise Error("Error: no spam")
Is this stupid, or what?
Thanks!
If you are just trying to make sure that required parameters are passed, just leave off the default value. Python will then automatically throw a TypeError if a parameter is missing.
def __init__( self, spam, eggs=0 )
If the argument isn't optional, why are you providing a default argument for it? The Python interpreter automatically raises an error if an argument without a default value isn't passed one.
In your specific example it would be simplest to not give spam
a default value -- Python will then diagnose the problem for you if the user forgets to pass that argument. (However, passing False
, 0
, []
, ... as spam
would be OK for Python, so if you have requirements against them you might have to additionally specify your own semantics checks).
If you do have to perform any diagnosis, raising an exception if it fails is sensible. However it should be the proper exception -- e.g., ValueError
if the value is of an acceptable type but not acceptable as its specific value -- and with a clear, complete message. So, summarizing:
class Breakfast(object):
def __init__(self, spam, eggs=0):
if not spam:
raise ValueError("falsish spam %r not acceptable" % (spam,))
(You do need to wrap spam
in a single-item tuple (spam,)
here, else passing an empty tuple as spam
would result in a complicated, confusing error;-).
In this special case, don't make spam a keyword:
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")
First of all I think you mean
if spam is None:
as Breakfast(0)
would be boolean True for not spam
as would be an argument of []
, 0.0
, ''
, u''
, etc.
Secondly, the Error raised is both of an uninformative generic class instead of a more typical ValueError
. Finally, exception text could be more informative and guide the caller to a fix.
And, as others have noted, you sacrificed automatic checking by setting a default for which there isn't one.
精彩评论