微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有一种干净的方法可以在 python 函数中将条件默认值设置为可选参数?

如何解决有没有一种干净的方法可以在 python 函数中将条件默认值设置为可选参数?

我有一个带有多个可选参数的函数,其认值以非可选参数为条件。

目前看起来像这样:

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,option_1,option_2,option_3,option_4)

然而这种风格打破了不重复代码的规则,而是使用循环。

所以我可以选择做这样的事情:

def foo_2(x,option_4=None):
    options = [option_1,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,*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,option_4):
    return x + y + option_1 + option_2 + option_3 + option_4

解决方法

我想如果是我并且这是您经常遇到的一种模式,如果我可以使用部分,我可能会考虑返工 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,option_1=None,option_2=None,option_3=None,option_4=None):
    option_1 = value_or_fallback(option_1,fallback_1,y)
    option_2 = value_or_fallback(option_2,fallback_2,y)
    option_3 = value_or_fallback(option_3,fallback_3,y)
    option_4 = value_or_fallback(option_4,fallback_4,y)
    return _foo(x,option_4)

print(foo(1,2))
print(foo(1,2,option_4=75))

或者更有可能的是,如果所有这些实用函数都/可以被限定为 foo(),那么我会用闭包构建 foo()

def build_foo():
    _get = lambda value,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,option_4: x + y + option_1 + option_2 + option_3 + option_4
    def foo(x,option_4=None):
        option_1 = _get(option_1,_fb_1,y)
        option_2 = _get(option_2,_fb_2,y)
        option_3 = _get(option_3,_fb_3,y)
        option_4 = _get(option_4,_fb_4,y)
        return _foo(x,option_4)
    return foo

foo = build_foo()
print(foo(1,option_4=75))

再次根据复杂性使用 lambdas 或函数 defs。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?