我有一个带有多个可选参数的函数,其默认值以非可选参数为条件。
目前看起来像这样:
def foo(x, y, option_1=None, option_2=None, option_3=None, option_4=None):
if option_1 is None:
option_1 = choose_option_1(x, y)
if option_2 is None:
option_2 = choose_option_2(x, y)
if option_3 is None:
option_3 = choose_option_3(x, y)
if option_4 is None:
option_4 = choose_option_4(x, y)
return _foo(x, y, option_1, option_2, option_3, option_4)
然而这种风格打破了不重复代码的规则,而是使用循环。
所以我可以选择做这样的事情:
def foo_2(x, y, option_1=None, option_2=None, option_3=None, option_4=None):
options = [option_1, option_2, option_3, option_4]
funcs = [choose_option_1, choose_option_2, choose_option_3, choose_option_4]
for i in range(len(options)):
if options[i] is None:
options[i] = funcs[i](x, y)
return _foo(x, y, *options)
然而,我认为第二个选项实际上不如第一个可读。
但在任何一种情况下,我都认为代码看起来不必要地完整、沉重,而且比最佳代码更难理解。
是否有更干净、更易读(也许更像 Python)的替代方案?
编辑:如果你想自己运行这段代码,这里有一些占位符函数你可以用来实现 foo:
def choose_option_1(x, y):
return x + y
def choose_option_2(x, y):
return x - y
def choose_option_3(x, y):
return x * y
def choose_option_4(x, y):
return x / y
def _foo(x, y, option_1, option_2, option_3, option_4):
return x + y + option_1 + option_2 + option_3 + option_4
答案 0 :(得分:0)
我想如果是我并且这是您经常遇到的一种模式,如果我可以使用部分,我可能会考虑返工 foo()
。也就是说,您还可以使用类似于 get()
的小实用函数来清理内容。如果可用则返回一个值,如果不可用则返回一个回退值。请注意,我假设这些函数都比这个例子更复杂,否则我会将它们全部实现为 lambdas...
value_or_fallback = lambda value, fn, x, y: value if value is not None else fn(x,y)
def fallback_1(x, y):
return x + y
def fallback_2(x, y):
return x - y
def fallback_3(x, y):
return x * y
def fallback_4(x, y):
return x / y
def _foo(x, y, option_1, option_2, option_3, option_4):
return x + y + option_1 + option_2 + option_3 + option_4
def foo(x, y, option_1=None, option_2=None, option_3=None, option_4=None):
option_1 = value_or_fallback(option_1, fallback_1, x, y)
option_2 = value_or_fallback(option_2, fallback_2, x, y)
option_3 = value_or_fallback(option_3, fallback_3, x, y)
option_4 = value_or_fallback(option_4, fallback_4, x, y)
return _foo(x, y, option_1, option_2, option_3, option_4)
print(foo(1,2))
print(foo(1,2, option_4=75))
或者更有可能的是,如果所有这些实用函数都/可以被限定为 foo()
,那么我会用闭包构建 foo()
:
def build_foo():
_get = lambda value, fn, x, y: value if value is not None else fn(x,y)
_fb_1 = lambda x, y: x + y
_fb_2 = lambda x, y: x - y
_fb_3 = lambda x, y: x * y
_fb_4 = lambda x, y: x / y
_foo = lambda x, y, option_1, option_2, option_3, option_4: x + y + option_1 + option_2 + option_3 + option_4
def foo(x, y, option_1=None, option_2=None, option_3=None, option_4=None):
option_1 = _get(option_1, _fb_1, x, y)
option_2 = _get(option_2, _fb_2, x, y)
option_3 = _get(option_3, _fb_3, x, y)
option_4 = _get(option_4, _fb_4, x, y)
return _foo(x, y, option_1, option_2, option_3, option_4)
return foo
foo = build_foo()
print(foo(1,2))
print(foo(1,2, option_4=75))
再次根据复杂性使用 lambdas 或函数 defs。