Pythonic方法有效地处理可变数量的返回参数

时间:2015-07-28 14:41:57

标签: python coding-style return-value calling-convention

所以我有一个可以安静地或冗长地工作的功能。在安静模式下,它会产生输出。在详细模式下,它还将中间计算保存到列表中,尽管这样做本身需要额外的计算。

在你问之前,是的,这是一个确定的优化瓶颈,很少需要详细的输出,所以没关系。

所以问题是,有效处理可能会或可能不会返回第二个值的函数的最pythonic方法是什么?我怀疑pythonic方式会被命名为元组或字典输出,例如

def f(x,verbose=False):
    result = 0
    verbosity = []
    for _ in x:
        foo = # something quick to calculate
        result += foo
        if verbose:
            verbosity += # something slow to calculate based on foo
    return {"result":result, "verbosity":verbosity}

但这需要在不需要的时候构建一个字典。

一些替代方案是:

# "verbose" changes syntax of return value, yuck!
return result if verbose else (result,verbosity)

或使用可变参数

def f(x,verbosity=None):
    if verbosity:
        assert verbosity==[[]]
    result = 0
    for _ in x:
        foo = # something quick to calculate
        result += foo
        if verbosity:
            # hard coded value, yuck
            verbosity[0] += # something slow to calculate based on foo
    return result

# for verbose results call as
verbosity = [[]]
f(x,verbosity)

有更好的想法吗?

2 个答案:

答案 0 :(得分:1)

不要返回verbosity。使它成为一个可选的函数参数,由调用者传入,如果不为空则在函数中进行变异。

一些答案​​的非pythonic部分是需要测试返回值的结构。为可选处理传递可变参数可以避免这种丑陋。

答案 1 :(得分:0)

我喜欢第一个选项,但不是在函数调用中传递verbose参数,而是返回一个快速结果的元组和一个延迟计算的函数:

import time

def getResult(x):
    quickResult = x * 2

    def verboseResult():
        time.sleep(5)
        return quickResult * 2

    return (quickResult, verboseResult)

# Returns immediately
(quickResult, verboseResult) = getResult(2)

print(quickResult)     # Prints immediately
print(verboseResult()) # Prints after running the long-running function