简体   繁体   中英

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
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) .

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

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')

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)

如果None会抛出错误,您可以直接使用该函数并处理错误但是您需要而不是提前检查。

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

pythonic的答案是:除非它是从用户输入(或其他程序或子系统或设置文件等)获取数据的子系统入口点,否则不要浪费你的时间进行这样的“验证”,只是使用传入的任何内容。这是调用者的负责传递有效参数,如果他不这样做,那么尝试使用参数将引发异常。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM