3

我有一个方法

    @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
4

7 回答 7

6
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[]

@DSM 对if None in (name, date...作品的建议也是如此 - 取决于您喜欢哪个。

旁注:您的函数需要很多参数。我想知道你是否不能以某种方式重构它——也许你可以创建一个Transaction封装这些数据的类,并将这个方法签名更改为add_transaction(transaction).

于 2013-04-18T20:49:42.207 回答
3
if None in (name, date, amount, debit, user, category_id):
    raise ValueError("I haz the Nones")
于 2013-04-18T20:53:13.990 回答
3

如果这是您计划经常使用的东西,您可能需要考虑使用装饰器:

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')
于 2013-04-18T20:55:38.643 回答
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)
于 2013-04-18T20:57:10.457 回答
1

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

于 2013-04-18T20:48:53.050 回答
1
def add_transaction(**kwargs):
    if None in kwargs.values():
         raise ValueError
于 2013-04-18T20:50:58.987 回答
0

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

于 2013-04-18T21:11:18.283 回答