默认参数混淆

Default Parameter Confusion

我知道 Python 的默认参数仅在创建函数时才被评估,但我在我的示例中感到困惑,为什么我的第一个默认参数每次都被重置,但我的空集却没有' t.

在下面,我从其他地方用日期列表调用 main_func()。然后遍历日期以从 api 中收集一堆数据。我需要为每个日期获取至少 100 个独特的数据,因此我为每个日期重复 __get_data_for_date 函数,直到它们有 100 个响应。当我进入下一个日期时,start_index 重置为 0,但我的 unique_data 集保留了之前的数据。

为什么 start_index 会重置而不是 unique_data

# when called from main_func, start_index is always reset but unique_data always keeps its data from the previous calls
def __get_data_for_date(date, start_index=0, unique_data=set()):
    data = api_call(date)

    data_set = unique_data

    for d in data:
        data_set.add(d['id'])

    if len(unique_data) < 100:
        return __get_data_for_date(date, start_index=start_index+len(data), unique_data=data_set)

    return data_set

def main_func(dates):
    final_data = []

    for date in dates:
        # start_index is back to 0 but unique_data still has the previous data
        data = __get_data_for_date(date)
        final_data.append(data)

    return final_data

start_index 永远不会重置。它从一开始就没有改变。

start_index是一个数字,是不可变的。因为它是不可变的,所以它永远不会改变。

把它比作一个集合,它是可变的,可以改变。当您执行 data_set.add(d['id']) 时,您是在直接改变(更改)存储为默认参数的对象。

因此,在这两种情况下,存储为默认参数的对象永远不会改变(您可以通过检查每个的 id 来验证这一点)。不同之处在于不可变数字本身永远不会改变,而可变集合是。


不过,需要明确的是,问题不在于集合是可变的。问题是它变了。如果你从不改变它,那么拥有一个可变的默认参数是安全的(假设你不会忘记它在未来是一个默认参数)。