【问题标题】:Is there an elegant way to manage multiple related functions through one big function? [duplicate]有没有一种优雅的方法可以通过一个大功能来管理多个相关功能? [复制]
【发布时间】:2021-06-21 11:57:45
【问题描述】:

编辑:
由于有些人显然误解了这个问题.. 我甚至不接近询问如何在 python 中进行开关/案例。请在投票结束之前阅读它。

我有 n 不同的函数,它们都高度相关,但参数略有不同。
作为一个比喻,考虑它们代表n 不同的排序算法。现在,我想要一个大的参数化函数sort,它从外部调用,然后在内部调用正确的排序算法/正确的函数。
作为附加要求,必须能够为所有这些子函数提供不同的输入信息(不同数量的参数)。

我想出了一个解决方案,但我觉得这是一种糟糕的风格。有更多经验的人可以对这个解决方案提出他/她的想法吗?

def function_one(*args):
    arg1, arg2 = args[0:2]
    # do something here
    
def function_two(*args):
    arg3, arg4 = args[2:4]
    # do something here

# imagine that here are more functions

def function_n(*args):
    arg1, arg3, arg5 = args[0], args[2], args[4]
    # do something here

switcher = {
    'one': function_one,
    'two': function_two,
    # ... imagine that here are more mappings
    'n': function_n
}

def some_super_function(arg0, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None, ..., argN=None):
    return switcher.get(arg0)(arg1, arg2, arg3, arg4, arg5, ..., argN)

【问题讨论】:

  • 对我来说,函数接受关键字参数比接受位置参数更有意义。切出大量位置参数感觉很脆弱。
  • 如果这些函数都采用不同的参数子集,它们应该是单独的函数。您可能想查看singledispatch,它可以让您定义一个通用函数,然后为不同的输入 types 添加新的实现。
  • @buran 我认为这不是问题所在,因为他们已经在使用 switch 等效项。
  • @Carcigenicate,看起来他们不确定这是不是好的风格。但由 OP 来告知或提供更多信息。
  • 我也会让“超级函数”具有相同的签名 - 就像其他函数一样。同样正如@Carcigenicate 所建议的那样 - 可能将所有函数切换为采用关键字参数,例如像def spam(**kwargs): 这样的超级函数def eggs(arg, **kwargs):

标签: python design-patterns


【解决方案1】:

我没有看到根据传递的参数选择函数的要求,因此您可以传递一些允许您选择函数的参数。

def function_one(*args):
    print(f'run function_one, args - {args}')
    # do something here


def function_two(*args):
    print(f'run function_two, args - {args}')
    # do something here


# imagine that here are more functions

def function_n(*args):
    print(f'run function_n, args - {args}')
    # do something here


switcher = {
    'one': function_one,
    'two': function_two,
    # ... imagine that here are more mappings
    'n': function_n
}


def some_super_function(func: str, *args):
    return switcher[func](args)

some_super_function('one', 1, 2, 3) # run function_one, args - ((1, 2, 3),)
some_super_function('two', '12', 'asdasda', 11) # run function_two, args - (('12', 'asdasda', 11),)
some_super_function('n', [1, 2, 3], {1: 2}, [123, 321]) # run function_n, args - (([1, 2, 3], {1: 2}, [123, 321]),)

【讨论】:

  • 我可能会采用类似的方法,因为我不再期待任何建设性的答案,因为问题被错误地标记为重复。
猜你喜欢
  • 1970-01-01
  • 2011-09-18
  • 2011-07-06
  • 2010-12-10
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多