首页 > 解决方案 > 如何告诉函数使用默认参数值?

问题描述

我有一个foo调用的函数math.isclose

import math
def foo(..., rtol=None, atol=None):
    ...
    if math.isclose(x, y, rel_tol=rtol, abs_tol=atol):
        ...
    ...

math.isclose如果我不通过rtol,上述atol失败foo

TypeError: must be real number, not NoneType

我不想将系统默认参数值放在我的代码中(如果他们在路上改变了怎么办?)

到目前为止,这是我想出的:

import math
def foo(..., rtol=None, atol=None):
    ...
    tols = {}
    if rtol is not None:
        tols["rel_tol"] = rtol
    if atol is not None:
        tols["abs_tol"] = atol
    if math.isclose(x, y, **tols):
        ...
    ...

这看起来又长又傻,并且dict在每次调用时 分配一个foo(它递归地调用自己,所以这重要)。

那么,告诉math.isclose使用默认公差的最佳方法是什么?

PS。有几个相关的问题。请注意,我不想知道实际的默认参数math.isclose- 所有我希望它告诉它使用默认值,无论它们是什么。

标签: pythonpython-3.x

解决方案


一种方法是使用可变参数解包:

def foo(..., **kwargs):
    ...
    if math.isclose(x, y, **kwargs):
        ...

这将允许您将atolrtol作为关键字参数指定给 main 函数foo,然后它将原封不动地传递给math.isclose.

但是,我还要说,传递的参数kwargs以某种方式修改函数的行为,而不是仅仅传递给被调用的子函数,这是惯用的。因此,我建议取而代之的是,命名一个参数,以便清楚地将其解包并原封不动地传递给子函数:

def foo(..., isclose_kwargs={}):
    ...
    if math.isclose(x, y, **isclose_kwargs):
        ...

matplotlib您可以在(例如:plt.subplots-subplot_kwgridspec_kw,所有其他关键字参数Figure作为**fig_kw)和seaborn(例如:FacetGrid- subplot_kws, )中看到等效模式gridspec_kws

当您可能想要传递关键字参数但保留默认行为时,这一点尤其明显:

def foo(..., f1_kwargs={}, f2_kwargs={}, f3_kwargs={}):
    ...
    f1(**f1_kwargs)
    ...
    f2(**f2_kwargs)
    ...
    f3(**f3_kwargs)
    ...

警告:

请注意,默认参数仅实例化一次,因此您不应修改dicts函数中的空参数。如果需要,您应该改为使用默认参数,并在每次运行函数时None实例化一个新的空:dict

def foo(..., isclose_kwargs=None):
    if isclose_kwargs is None:
        isclose_kwargs = {}
    ...
    if math.isclose(x, y, **isclose_kwargs):
        ...

我的偏好是在你知道自己在做什么的地方避免这种情况,因为它更简短,而且总的来说我不喜欢重新绑定变量。但是,它绝对是一个有效的成语,并且可以更安全。


推荐阅读