我有像
这样的方法 @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 :(得分: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
,如果任何参数为False
,0
,[]
等,您将最终提出异常,这不是您想要的。
@ DSM对if None in (name, date...
的建议也适用 - 这取决于您喜欢的内容。
旁注:你的函数需要很多参数。我想知道你是否不能以某种方式重构它 - 也许你可以创建一个封装这些数据的Transaction
类,并将此方法签名更改为add_transaction(transaction)
。
答案 1 :(得分:2)
if None in (name, date, amount, debit, user, category_id):
raise ValueError("I haz the Nones")
答案 2 :(得分: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)
,这仍然是假的。我们可以使用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')
答案 3 :(得分: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)
答案 4 :(得分:1)
如果None会抛出错误,你可以直接找到该函数并处理错误,但不要提前检查。
答案 5 :(得分:1)
def add_transaction(**kwargs):
if None in kwargs.values():
raise ValueError
答案 6 :(得分:0)
pythonic的答案是:除非它是从用户输入(或其他程序或子系统或设置文件等)获取数据的子系统入口点,否则 dont 会浪费你的时间进行这样的“验证”和只使用传入的内容。调用者负责传递有效参数,如果他不这样做,那么尝试使用参数会引发异常。