首页 > 解决方案 > 如何处理设计中的可选参数?

问题描述

有时我有这样的功能:

def my_func(arg1, arg2, arg3):
  pass

其中一个或两个是可选的,这是有道理的。但是,同时不存在所有 3 个参数是没有意义的。看来我有两种处理方法:

  1. 只需使用一个 'my_func' 并将所有 3 个参数保留为可选。在函数内部,我可以进行检查:

    def my_func(arg1=None, arg2=None, arg3=None):
    
     if arg1 is None and arg2 is None and arg3 is None:
        raise ValueError("Invalid arguments. Cant be None at the same time!")
    
  2. 将 my_func() 拆分为 2 个或三个函数,这些函数至少需要 arg 存在:

    def my_func_1(arg1, arg2=None, arg3=None):
      pass
    
    def my_func_2(arg1, arg2, arg3=None):
      pass
    

当参数数量增加时,事情变得更加复杂。对于拆分,实现更简单,但可能有冗余代码。对于一个单独的func,用户界面不是很清晰,实现会比较复杂,需要大量的if...else检查。

我个人更喜欢第一个 1-function 方法。这种情况有好的做法吗?

标签: python

解决方案


如果您需要对多个函数执行此检查,则可以编写一个装饰器来处理 arg 检查。

from functools import wraps

def not_all_none(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        cond_args = all(a is None for a in args)
        cond_kw = all(v is None for v in kwargs.values())

        if cond_args and cond_kw:
            raise ValueError("All arguments cannot be None at the same time.")
        
        return fn(*args, **kwargs)
    return wrapper

@not_all_none
def my_func(arg1=None, arg2=None, arg3=None):
    return True

这需要至少一个论点 not be None

my_func()
# raises:
ValueError: All arguments cannot be None at the same time.

my_func(0)
# returns:
True

my_func(arg2=100)
# returns:
True

您可以将其用于任何需要至少一个非无输入的功能。

@not_all_none
def other_func(a, b=0, c=None, d=None, e=None, f=None):
    return True

other_func(None)
# returns:
True

other_func(None, None)
# raises
ValueError: All arguments cannot be None at the same time.

推荐阅读