python - 如何告诉函数使用默认参数值?
问题描述
我有一个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
- 所有我希望它告诉它使用默认值,无论它们是什么。
解决方案
一种方法是使用可变参数解包:
def foo(..., **kwargs):
...
if math.isclose(x, y, **kwargs):
...
这将允许您将atol
和rtol
作为关键字参数指定给 main 函数foo
,然后它将原封不动地传递给math.isclose
.
但是,我还要说,传递的参数kwargs
以某种方式修改函数的行为,而不是仅仅传递给被调用的子函数,这是惯用的。因此,我建议取而代之的是,命名一个参数,以便清楚地将其解包并原封不动地传递给子函数:
def foo(..., isclose_kwargs={}):
...
if math.isclose(x, y, **isclose_kwargs):
...
matplotlib
您可以在(例如:plt.subplots
-subplot_kw
和gridspec_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):
...
我的偏好是在你知道自己在做什么的地方避免这种情况,因为它更简短,而且总的来说我不喜欢重新绑定变量。但是,它绝对是一个有效的成语,并且可以更安全。