daydreamer
daydreamer

Reputation: 91969

How do you check if any of the arguments passed to function is None?

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

Answers (7)

mgilson
mgilson

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

bruno desthuilliers
bruno desthuilliers

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

Benjamin Hodgson
Benjamin Hodgson

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

Jon Clements
Jon Clements

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

tdelaney
tdelaney

Reputation: 77347

if None in (name, date, amount, debit, user, category_id):
    raise ValueError("I haz the Nones")

Upvotes: 5

0x90
0x90

Reputation: 40982

def add_transaction(**kwargs):
    if None in kwargs.values():
         raise ValueError

Upvotes: 1

BWStearns
BWStearns

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

Related Questions