简体   繁体   English

有没有办法通过两个函数传递可选参数?

[英]Is there a way to pass optional parameters through two functions?

Question " Is there a way to pass optional parameters to a function? " describes how default keyword parameters are used. 问题“ 有没有办法将可选参数传递给函数? ”描述了如何使用默认关键字参数。

I have two functions, one of which calls the other, and I want to be able to detect if the outer function was called with an optional parameter: 我有两个函数,其中一个函数调用另一个函数,我希望能够检测外部函数是否使用可选参数调用:

def foo(x1, opt=None):
    bar(opt)

def bar(opt=5):
    print opt

if __name__ == '__main__':
    foo(1)           # Should print 5, actually prints None
    foo(2, opt=3)    # Does print 3

This prints: 这打印:

None
3

Foo() could be written with special logic to detect whether the optional parameter is passed, but is there a pythonic way to pass an optional parameter with its optionality preserved without using extra logic? 可以使用特殊逻辑编写Foo()以检测是否传递了可选参数,但是是否有一种pythonic方法来传递可选参数,并保留其可选性而不使用额外的逻辑?

def foo2(x1, opt=None):
    if opt is None:
        bar()
    else:
        bar(opt)

The default has to be defined at the inner function because it could be called directly. 默认必须在内部函数中定义,因为它可以直接调用。 I could also define the same default for inner and outer functions, but that's a bit ugly (violates DRY) when the default is more complex than an integer. 我也可以为内部和外部函数定义相同的默认值,但是当默认值比整数更复杂时,这有点难看(违反DRY)。

One thing that you could do is use the **kwargs syntax to allow for any keyword arguments to be passed through, and then just raise errors if there are any extra keywords that don't mean anything (or alternatively, just cleanly ignore them, though that confuses users in case they make a typo and no error occurs). 您可以做的一件事是使用**kwargs语法来允许传递任何关键字参数,然后只是在有任何额外的关键字没有任何意义的情况下引发错误(或者,只是干净地忽略它们,虽然这会让用户感到困惑,以防万一他们输入拼写错误并且没有错误发生)。 In the case of cleanly ignoring them: 在干净地忽略它们的情况下:

def foo(x1, **kwargs):
    if "opt" in kwargs:
        bar(kwargs["opt"])
    else:
        bar()

Basically, the **kwargs lets you pass in any keyword arguments like foo(opt = 3) and puts them all in a dict. 基本上, **kwargs允许您传入任何关键字参数,如foo(opt = 3) ,并将它们全部放入dict中。 The downside to this is that you cannot call it like foo(3) . 这样做的缺点是你不能像foo(3)那样称呼它。 If you want to go by placement arguments instead of keyword arguments, you can do *args which gives a tuple of the arguments, but then you are unable to call it with the keyword specified. 如果你想通过放置参数而不是关键字参数,你可以做*args ,它给出了参数的元组,但是你无法用指定的关键字调用它。 You cannot do both, unfortunately. 不幸的是,你无法做到这两点。

Since opt is not specified, it defaults to None as you have seen. 由于未指定opt,因此您可以看到默认为None。 This gives a definition to opt, and it does not remember or retain any property that it is a default value, so no, implementing logic here is mandatory for the required result. 这给了opt的定义,并且它不记得或保留任何属性它是默认值,所以不,这里实现逻辑对于所需的结果是必需的。

Perhaps just set the default argument in both places: 也许只需在两个地方设置默认参数:

DEFAULT_OPT = 5

def foo(x1, opt=DEFAULT_OPT):
    bar(opt)

def bar(opt=DEFAULT_OPT):
    print opt 

Otherwise use kwargs which I tend to avoid for being hard to maintain: 否则使用我倾向于避免难以维护的kwargs

def foo(x1, **kwargs):
    bar(**kwargs)

def bar(opt=5, **_):
    print opt 

In foo you call bar with opt . foo你可以opt bar This overwrites the default value of opt inside bar . 这将覆盖默认值, opt里面bar

None is an object in Python (see here ) This means that it is a valid argument, when you pass None to bar. None是Python中的对象(参见此处 )这意味着当您将None传递给bar时,它是一个有效的参数。 That's why it does not trigger the default parameter value 5. I don't know anything else in Python, which may do so. 这就是为什么它不会触发默认参数值5.我不知道Python中的任何其他内容,可能会这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM