Python 如何检查传递给函数的任何参数是否为None?
我有一个类似的方法Python 如何检查传递给函数的任何参数是否为None?,python,Python,我有一个类似的方法 @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 如果没有人会抛出错误,您可以直接使用函数,按照自己
@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
如果没有人会抛出错误,您可以直接使用函数,按照自己的意愿处理错误,而不是提前检查
if any(arg is None for arg in (name, date, amount, debit, user, category_id))):
raise ValueError("I hate None")
您需要测试arg是否为None
,而不仅仅是使用not
。使用not
,如果任何参数是False
、0
、[]
等,则最终会引发异常,而这不是您想要的
@DSM建议,如果(姓名、日期…中没有,则也有效-取决于您的喜好
旁注:您的函数需要很多参数。我想知道您是否能够以某种方式重构它-也许您可以创建一个封装此数据的事务类,并将此方法签名更改为add\u事务(Transaction)< /p> > 如果这是你计划使用的东西,你可能需要考虑一个装饰器:
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)
,仍然会出现这种情况。我们可以使用以下模块解决此问题:
可以使用装饰师并执行以下操作:
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)
pythonic的答案是:除非是从用户输入(或其他程序或子系统或设置文件等)获取数据的子系统入口点,否则不要浪费时间进行这种“验证”调用方有责任传递有效的参数,如果他不这样做,那么尝试使用这些参数将引发异常。您确定要使用'or'和'not'和'?他想要或
,这样,如果至少有一个参数是None
my,就会引发ValueError
糟糕,我纠正了它你的意图是什么?像关键字参数这样的东西可能更好!如果这是我的代码,我会把这些参数放在一个列表中,并说如果不是全部(列表参数)
…为什么不在(名称…)中没有?因为在(名称…)中没有
测试的是平等,而不是身份。@Lennartreegebro:如果有人不正当地制造了一个测试结果等于无的对象,你是谁来反驳他呢?6个论点不是“很多”而且我们没有足够的上下文来知道添加事务类型是否是正确的做法。@Brunodesshuilliers:我们不知道上下文是对的,这只是一个建议。“多少就是太多了”这是一个个人偏好的问题-我想说六个参数太多了。缺点是你没有为未指定的关键字获取默认值,或者为无效的关键字获取错误。对于自动文档来说,下选-命名参数是一个好东西(tm),并且**Kwarg应该为两个通用函数保留(decorators等)或可选参数。向上投票-只要您的函数不是子系统的入口点,调用方就有责任传递有效的参数。True-fact.Was[不合理地]继续那个假设。@JonClements--谢谢。我实际上是想弄清楚我是否可以检查参数,并用相同的签名创建一个new_func
,但我不确定这是可能的。这不需要。唯一的情况是我们的答案(我现在能想到)如果提供了太多的参数,并且装饰程序会失败,这将是错误的,因为其中一个参数是None,而不是函数调用失败,因为参数太多arguments@JonClements--出于文档目的,这很好,我在你的帖子上发布了另一个案例,我们的案例将失败。装饰师太棒了,我写了我的第一个案例根据您的建议,非常感谢!这个(和我的)唯一的问题是,如果用户通过关键字调用参数:Testing.add\u transaction(1,2,3,4,5,category\u id=None)
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')
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')
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)