非标准可选参数默认值

时间:2009-07-13 09:23:49

标签: python optional-arguments

我有两个功能:

def f(a,b,c=g(b)):
    blabla

def g(n):
    blabla

c是函数f中的可选参数。如果用户未指定其值,则程序应计算g(b),这将是c的值。但是代码没有编译 - 它说名称'b'没有定义。如何解决?

有人建议:

def g(b):
    blabla

def f(a,b,c=None):
    if c is None:
        c = g(b)
    blabla

但这不起作用。也许用户希望c为无,然后c会有另一个值。

5 个答案:

答案 0 :(得分:26)

def f(a,b,c=None):
    if c is None:
        c = g(b)

如果None可以是c的有效值,那么请执行以下操作:

sentinel = object()
def f(a,b,c=sentinel):
    if c is sentinel:
        c = g(b)

答案 1 :(得分:2)

c的值将在编译时进行评估(g(b))。因此,您需要在g之前定义f。当然,您还需要在该阶段定义全局b变量。

b = 4

def g(a):
    return a+1

def test(a, c=g(b)):
    print(c)

test(b)

打印5。

答案 2 :(得分:2)

你不能这样做。

在函数内部,检查是否指定了c。如果没有,请进行计算。

def f(a,b,c=None):
    if c == None:
        c = g(b)
    blabla

答案 3 :(得分:1)

的问题
sentinel = object()
def f(a, b, c=sentinel):
  if c is sentinel:
    c = g(b)

sentinel是全局/公共的,除非此代码是函数/方法的一部分。所以有人可能仍然可以致电f(23, 42, sentinel)。但是,如果f是全局/公共的,您可以使用闭包使sentinel本地/私有,以便调用者无法使用它:

def f():
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f()

如果您担心静态代码分析器可能会错误地了解f,那么您可以为工厂使用相同的参数:

def f(a, b, c=object()): #@UnusedVariable
  sentinel = object()
  def tmp(a, b, c=sentinel):
    if c is sentinel:
      c = g(b)
  return tmp
f = f(23, 42)

答案 4 :(得分:0)

def f(a,b,*args):
    if len(args) == 1:
        c = args[0]
    elif len(args) == 0:
        c = g(b)
    else:
        raise Exception('Function takes 2 or 3 parameters only.')
    blabla

def g(n):
    blabla

你可以更好地构建它,但这是主要的想法。或者,您可以使用**kwargs并使用f(a,b,c=Something)之类的功能,您只需相应地修改f

Documentation