如何传播默认值

时间:2018-11-02 17:16:52

标签: python

支持我已经定义了一些功能,例如(非常简单的示例)

def f1(a, b, arg='something'):
   ...
def f2(c, arg='else'):
   ...

然后我称它们为:

def f(a, b, c):
   return f1(a, b) + f2(c)

由于这是非常常用的方法,但是我想分别定义f1f2,以便可以只调用一个。

我希望在调用f时使用不同的默认参数调用f1f2的可能性,所以我可以这样做:

def f(a, b, c, arg1='something', arg2='else'):
   return f1(a, b, arg1) + f2(c, arg2)

这不是非常可维护的(我的功能比2多得多,并且参数更多),因为当我更新一个功能时,我需要更新f。 一种选择是使用None作为默认值,然后在函数主体内更改它们,例如

def f1(a, b, arg=None):
   arg = arg or 'something'
   ...

,但这会从签名中隐藏默认参数的实际值。 另外,这不能解决我所有的问题,因为如果我向f1添加一个新参数,则必须更改f的签名及其实现...

3 个答案:

答案 0 :(得分:1)

听起来您已经到了面向对象编程可以为您提供帮助的地步。您可以将函数重写为一个类:

class FFuncs:
        def __init__(self, a, b, c, arg1="foo", arg2="bar"):
            self.a = a
            self.b = b
            self.c = c
            self.arg1 = arg1
            self.arg2 = arg2
        def f1(self):
          return str(self.a + self.b) + self.arg1
        def f2(self):
          return str(self.c) + self.arg2
        def f(self):
          return self.f1() + self.f2()

FFuncs(2, 3, 5, arg1=" Foos and ", arg2=" Spam").f()
# Returns "5 Foos and 5 Spam"

现在,每次执行之前,您始终可以访问kwarg的默认值。就像评论中提到的那样,如果您对类的任何给定方法都需要特别灵活的调用签名,则仍然可以使用*args, **kwargs进行抽象。

答案 1 :(得分:0)

尝试使用此功能!

def f(a, b, c, *args):
   if len(args)==2:
      return(f1(a, b, args[0]) + f2(c, args[1]))
   else:
      return(f1(a, b, None) + f2(c, None))

答案 2 :(得分:0)

def f1(a, b, arg='something', **kwargs):
   pass
def f2(c, arg='else', **kwargs):
   pass
def f(a, b, c, arg1='something', arg2='else'):
   kwargs = locals()
   return f1(**kwargs) + f2(**kwargs)

如果您希望同时获得动态委托和静态定义这两个东西,这是最简单的解决方案,但并不理想:

  • 您必须在函数中添加**kwargs,以便在传递太多参数时它们不会失败;
  • 您将很容易在重命名参数时遇到逻辑错误,例如将c中的f2重命名为b

如果您有许多fn函数,则return行可能会像这样结束:

return sum(f(**kwargs) for f in (f1, f2, ..., fn))