Reputation: 91969
I have a method like
@staticmethod
def add_transaction(name, date, amount, debit, user, category_id):
pass
What is the best way to test if any of them is None
?
if not (name or date or amount or debit or user or category_id):
raise ValueError
Upvotes: 3
Views: 6653
Reputation: 309929
If this is something you plan on using a lot, you might want to consider a decorator:
import functools
def None_is_dumb_and_does_not_deserve_to_enter_this_function(func):
@functools.wraps(func)
def new_func(*args,**kwargs):
if None in args:
raise ValueError("None's aren't welcome here")
return func(*args,**kwargs)
return new_func
@None_is_dumb_and_does_not_deserve_to_enter_this_function
def foo(a,b,c):
"""Docstring"""
print a,b,c
foo(1,2,3)
print foo.__doc__
foo(None,'bar','baz')
This still fais if you call foo(1,2,c=3)
. We can fix that using the decorator
module:
import decorator
@decorator.decorator
def no_none(f,*args,**kwargs):
if None in args:
raise ValueError("None's aren't welcome here")
return f(*args,**kwargs)
@no_none
def foo(a,b,c):
"""Docstring"""
print a,b,c
foo(1,2,3)
print foo.__doc__
try:
foo(None,'bar','baz')
except ValueError as e:
print ('Good, raised ValueError')
try:
foo("bar","baz",c=None)
except ValueError as e:
print ('Good, raised ValueError')
Upvotes: 3
Reputation: 77912
The pythonic answer is: unless it's a subsystem entry point taking data from user inputs (or another program or subsystem or a settings file etc), just dont waste your time with such "validation" and just use whatever was passed in. It's the caller's responsability to pass valid arguments, and if he doesn't then trying to use the arguments will raise an exception anyway.
Upvotes: 0
Reputation: 44634
if any(arg is None for arg in (name, date, amount, debit, user, category_id))):
raise ValueError("I hate None")
You need to test arg is None
, rather than just using not
. With not
, you'll end up raising an exception if any of the arguments are False
, 0
, []
, etc, which is not what you want.
@DSM's suggestion of if None in (name, date...
works as well - it's up to you which you prefer.
Side note: your function takes a lot of arguments. I wonder if you couldn't refactor it in some way - perhaps you could make a Transaction
class that encapsulates this data, and change this method signature to add_transaction(transaction)
.
Upvotes: 7
Reputation: 142156
Could use a decorator and do something like:
from functools import wraps
def no_none(f):
def wrapper(*args, **kwargs):
if any(parm is None for parm in args):
raise ValueError('None not allowed')
return f(*args, **kwargs)
return wrapper
class Testing(object):
@staticmethod
@no_none
def add_transaction(name, date, amount, debit, user, category_id):
pass
Testing.add_transaction(1, 2, 3, 4, 5, 6)
Testing.add_transaction(1, 2, 3, 4, 5, None)
Upvotes: 2
Reputation: 77347
if None in (name, date, amount, debit, user, category_id):
raise ValueError("I haz the Nones")
Upvotes: 5
Reputation: 40982
def add_transaction(**kwargs):
if None in kwargs.values():
raise ValueError
Upvotes: 1
Reputation: 2706
If None would throw an error you could just go for the function and handle the error however you wanted instead of checking ahead of time.
Upvotes: 1