2013-04-18 50 views
2

我有这样如何检查传递给函数的任何参数是否为None?

@staticmethod 
    def add_transaction(name, date, amount, debit, user, category_id): 
     pass 

什么是测试如果他们中任何一个None最好的方式方法?

if not (name or date or amount or debit or user or category_id): 
    raise ValueError 
+0

您确定要使用'or'而不是'and'吗? – JonathanV

+0

他希望'或',以便如果至少有一个参数是'None',那么就会引发'ValueError'。 – 1337holiday

+0

我不好,我改正了它 – daydreamer

回答

2

如果这是您计划使用了很多的东西,你可能要考虑一个装饰:

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

如果你打电话foo(1,2,c=3)这仍然FAIS。我们可以修复使用decorator模块:

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

@JonClements - 谢谢。其实我试图弄清楚我是否可以检查参数并使用相同的签名创建'new_func' ......但我不确定这是可能的。 – mgilson

+0

这不需要。我们的答案(我现在能想到的)的唯一情况是错误的是提供的参数太多,并且装饰器会失败,因为其中一个是None,而不是函数调用失败,因为参数太多 –

+0

@JonClements - 这是很好的文件的目的,我发布了一个替代案例,我们的将在您的文章上失败。 – mgilson

1

如果没有将抛出一个错误,你可以只去的功能和处理,但是你想检查的时间提前,而不是错误。

+0

Upvoted - 只要你的函数不是子系统的入口点,它就是调用者传递有效参数的责任。 –

+0

真实的事实。 [无理地]按这个假设行事。 – BWStearns

4
if any(arg is None for arg in (name, date, amount, debit, user, category_id))): 
    raise ValueError("I hate None") 

您需要测试arg is None,而不是仅仅使用not。用not,如果有任何参数是False0[]等,您将最终引发异常,这不是您想要的。

@帝斯曼对if None in (name, date...的建议也适用 - 它取决于您的喜好。

注意:你的函数需要大量的参数。我想知道你是否不能以某种方式重构它 - 也许你可以创建一个封装这个数据的类,并将这个方法签名改为add_transaction(transaction)

+2

..为什么不在'(名字,...)'中没有? – DSM

+1

因为'(名称,...)中没有'测试的是平等,而不是身份。 –

+0

@LennartRegebro:如果有人倒过来做了一个等于'None'的对象,那么你是谁呢? – DSM

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

不足之处在于,您无法获取非指定关键字的默认值或无效关键字的错误。 – tdelaney

+1

downvoted - 命名参数是一个用于自动文档的GoodThing(tm),而** kwargs应该为通用函数(装饰器等)或可选参数保留。 –

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

可以使用装饰和做类似:

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) 
+0

这个(和我的)唯一的问题是,如果用户通过关键字调用参数,它会中断:'Testing.add_transaction(1,2,3,4,5,category_id = None)' – mgilson

0

的Python的答案是:除非它是由用户输入一个子系统条目点取得的数据(或另一个程序或子系统或设置文件等),只需不要这样的“验证”浪费你的时间,只是使用传入的任何东西。这是调用者的通过有效参数的责任,如果他不然后尝试使用无论如何,争论都会引发异常。

相关问题