如何将参数的默认值从一个函数定义传递给更高的一个

时间:2016-06-26 20:41:38

标签: python

我正在寻找一种将参数的默认值传递给调用函数的好方法。让我通过例子解释一下:

def greet(name, greeting='Hello', punctuation='!'):
    return greeting+' '+name+punctuation

def greet_with_hi(name, punctuation='!'):
   return greet(name, 'Hi', punctuation)

这是一个没有用的示例,但这里是我的问题:如何省略puncuation greet_with_hi参数的默认值?此参数的默认值已在greet中定义。

我能想到的解决方案:

  • 让它原样,缺点:必须在每个功能定义上更改默认值,而不是仅在一个地方更改
  • 使用None作为默认参数的值,并在None内处理greet,缺点:特殊处理
  • 使用全局"常数"像DEFAULT_PUNCTUATION='!'一样使用它作为默认参数的值,缺点:似乎不是非常pythonic

我还没有看到API和其他代码中的常见模式。你会如何处理这种模式?

3 个答案:

答案 0 :(得分:3)

为什么不使用None

def greet(name, greeting='Hello', punctuation='!'):
    return greeting+' '+name+punctuation

def greet_with_hi(name, punctuation=None):
    if punctuation:
        return greet(name, 'Hi', punctuation)
    else:
        return greet(name, 'Hi')

确实任何特殊值都可以使用,但{/ 1}}更好用于if / else。

如果希望None空字符串是有效的标点符号,则必须指定: ""

通常,模式是包装器设置包装函数中必需参数的默认值:

if punctuation is not None:

这个想法是def greet(name, greeting, punctuation): return greeting+' '+name+punctuation def greet_with_hi(name, punctuation='!'): return greet(name, 'Hi', punctuation) 是一般情况,greet()为你做了一些工作。

答案 1 :(得分:2)

如果不修改greet函数,只需从greet_with_hi函数中删除参数,并且不为参数传递任何内容。这样,将使用greet上定义的默认值:

def greet_with_hi(name):
    return greet(name, 'Hi')

如果您希望能够使用punctuationgreet_with_hi指定不同的值,但仍希望使用greet上指定的默认值,那么您可以这样做这样:

def greet_with_hi(name, punctuation = None):
    if punctuation is None:
        return greet(name, 'Hi')
    else:
        return greet(name, 'Hi', punctuation)

不幸的是,没有值传达“使用默认值”的含义,因此您只能通过不向其传递参数来触发greet的默认值。

或者,你也可以在这里使用元组解包,所以你只需要在这里指定一次参数。当你有多个默认参数时,这可能更有意义 - 此时你可能也想使用命名参数):

def greet_with_hi(name, punctuation = None):
    additionalArgs = []
    if punctuation is not None:
        additionalArgs.append(punctuation)
    return greet(name, 'Hi', *additionalArgs)

答案 2 :(得分:1)

让我们稍微简化一下你的问题。我们有两个函数,ab正在使用它。

def a(arg = 0):
    return arg

def b(arg = 0):
    return a(arg)

并且您希望他们共享默认参数值。

您可以简单地创建一个全局变量并在两个定义中使用它:

__DEFAULT_VALUE = 0

def a(arg = __DEFAULT_VALUE):
    return arg

def b(arg = __DEFAULT_VALUE):
    return a(arg)

其他解决方案是将b的defalt参数设为None,然后检查它。

def a(arg = 0):
    return arg

def b(arg = None):
    if arg is None:
        return a()
    return a(arg)

编辑:不要像下面的解决方案那样代码。已经很晚了,我很困,它来自哪里。

或者你可以使用更复杂和pythoney的方法。首先,extract default arguments from the "base" a function,然后将b的默认值设置为无,并检查是否已使用。如果是,则改为使用a的默认值。

import inspect

def a(arg=0):
    return arg

def b(arg=None):
    if arg is None:
        signature = inspect.getargspec(a)
        unpacked_signature = dict(zip(signature.args[-len(signature.defaults):], signature.defaults))
        arg = unpacked_signature['arg']

    return a(arg)