【问题标题】:Is there a way to pass optional parameters through two functions?有没有办法通过两个函数传递可选参数?
【发布时间】:2018-05-24 03:37:35
【问题描述】:

问题“Is there a way to pass optional parameters to a function?”描述了如何使用默认关键字参数。

我有两个函数,其中一个调用另一个,我希望能够检测是否使用可选参数调用了外部函数:

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

打印出来:

None
3

Foo() 可以用特殊的逻辑编写来检测是否传递了可选参数,但是有没有一种 Pythonic 的方式来传递一个可选参数,并且在不使用额外逻辑的情况下保留其可选性?

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

默认值必须在内部函数中定义,因为它可以直接调用。我也可以为内部函数和外部函数定义相同的默认值,但是当默认值比整数更复杂时,这有点难看(违反 DRY)。

【问题讨论】:

  • 我只是在纠结这个问题:如果您需要为内部和外部函数定义两个不同的默认值,您是否有设计问题?
  • 这有帮助吗:docs.python.org/3/faq/…
  • 我认为如果您通过改写代码以使用有意义的函数和参数名称而不是 foox1opt 等来解释上下文会有所帮助。我从字面上理解您的意思'正在询问,但如果不了解您要解决的实际问题,就很难提供意见。
  • @NPE,无意义的名称是重现问题的最简单方法。实际用例是内部函数在给定一些参数的情况下生成一个(非常长的)字符串,而外部函数在给定这些参数和文件名的情况下编写一个包含该输出的文件。更具体地说,字符串/文件的内容是 HTML5 文档。

标签: python


【解决方案1】:

您可以做的一件事是使用**kwargs 语法允许传递任何关键字参数,然后如果有任何没有任何意义的额外关键字(或者,只是干净忽略它们,尽管这会使用户感到困惑,以防他们打错字并且没有发生错误)。在完全忽略它们的情况下:

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

基本上,**kwargs 允许您传入任何关键字参数,例如foo(opt = 3),并将它们全部放在一个字典中。这样做的缺点是你不能像foo(3) 这样称呼它。如果你想通过放置参数而不是关键字参数,你可以做*args,它给出一个参数的元组,但是你不能用指定的关键字调用它。很遗憾,你不能同时做到这两点。

【讨论】:

  • 你不需要使用**kwargs; if opt is None: bar() else bar(opt).
  • @chepner 我的解决方案可以让你调用foo(None)foo() 有不同的含义。
  • 我担心是这样,但只是想确认没有可用的魔法酱。谢谢。
  • @Dave 不幸的是,我不相信您可以以适用于 Python 的方式进行反射。
【解决方案2】:

由于未指定 opt,因此它默认为 None ,如您所见。这给出了 opt 的定义,它不记住或保留它是默认值的任何属性,所以不,这里的实现逻辑对于所需的结果是强制性的。

【讨论】:

    【解决方案3】:

    也许只是在两个地方都设置了默认参数:

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

    否则使用kwargs,因为难以维护,我倾向于避免:

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

    【讨论】:

      【解决方案4】:

      foo 中,您使用opt 调用bar。这会覆盖baropt 的默认值。

      【讨论】:

      • 是的,就是这样。我相信 OP 知道这一点并且正在询问如何解决这个问题......
      【解决方案5】:

      None 是 Python 中的对象(请参阅here)这意味着当您将 None 传递给 bar 时,它是一个有效的参数。这就是为什么它不会触发默认参数值5。我不知道Python中的其他任何东西,可能会这样做。

      【讨论】:

        猜你喜欢
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-31
        • 1970-01-01
        • 2013-06-19
        相关资源
        最近更新 更多