Python 可选但有条件的参数

Python 可选但有条件的参数,python,arguments,Python,Arguments,假设我有一个函数,它有两个参数,但至少应该有一个: def foo_bar(foo = None, bar = None): 问题是它们都是可选的,但实际上会传入foo或bar。 现在,我检查函数中是否存在如下内容: do_this() if foo else do_that() sort of logic.. def foo(param, flag): if flag == 'foo': do_this() elif flag == 'bar':

假设我有一个函数,它有两个参数,但至少应该有一个:

 def foo_bar(foo = None, bar = None):
问题是它们都是可选的,但实际上会传入
foo
bar
。 现在,我检查函数中是否存在如下内容:

do_this() if foo else do_that() sort of logic.. 
def foo(param, flag):
    if flag == 'foo':
        do_this()
    elif flag == 'bar':
        do_that()
    else:
        raise ValueError()
但我不喜欢这个样子


处理这个问题的最佳方法是什么?

为什么不简单地检查一下哪一个没有,然后说另一个必须是存在的

if foo == None:
    do bar()
elif bar == None:
    do foo()
else:
    throwUpYourHandsInFrustration()

我想你是对的。还可以使用
kwargs
语法读取参数:

def foo(*args, **kwargs):
    if 'foo' in args:
        do_this()
    elif 'bar' in args:
        do_that()
    else:
        raise ValueError()
或者,你可以这样做:

do_this() if foo else do_that() sort of logic.. 
def foo(param, flag):
    if flag == 'foo':
        do_this()
    elif flag == 'bar':
        do_that()
    else:
        raise ValueError()

两种方式都可以。希望这有助于

3种解决方法浮现在脑海中:

如果可以根据有关参数的某些规则(一个是一种类型,一个是另一种类型,一个匹配1个正则表达式,一个匹配另一个,等等)切换行为,则传递一个参数并确定在函数内部执行的操作

创建两个函数,它们都为共享行为调用其他函数,但独立处理特定于foo和bar的情况

传递1个数据值和另一个控制值:

def foo_bar(val, control):
    if control=='foo':
        #Do foo stuff
    elif control=='bar':
        #Do bar stuff

您所处的轨道是正确的,但是如果两者都指定了呢?我通常做的是:

def some_func(foo=None, bar=None):
    "either one, or neither, but not both, are allowed"
    if foo is not None and bar is not None:
        raise TypeError("cannot specify both 'foo' and 'bar'")
    if foo is not None:
        pram = foo
    elif bar is not None:
        pram = bar
    else:
        pram = None  # or whatever

简单易懂。

你想过改用关键字args吗?@JoelCornett:OP已经在使用关键字参数了。@SvenMarnach:我的意思是
**kwargs
。如果两个参数都
,会不会是一个错误,还是不太可能?@SvenMarnach:这些似乎是带有默认值的位置参数。不确定**kwargs版本与原始版本相比有什么更好的地方。。。不过我喜欢param/flag版本。它就像你说的那样可以作为标志使用。它还允许以任何(基本上无顺序的)顺序传递参数。
dict的键/值对成为参数传递(和解析)的方式,而不是参数的位置传递,如果函数签名是
def foo(param1,param2,…)
。另外,请查看“我知道它是如何工作的”的答案,但是使用像
def foo(x,y,z)
这样的签名,您也可以按名称以任何顺序传递参数(
foo(z=1,x=2,y=3)
),这就是为什么我不确定
**kwargs
签名在这种情况下是否有任何优势的原因。