我有一个函数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
作为关键字参数的主要功能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):
...
我的偏好是避免这种情况,因为它比较简短,因此您不知道自己在做什么,而且一般而言,我不喜欢重新绑定变量。但是,这绝对是一个有效的习惯用法,它可以更安全。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句