龙空技术网

为什么不建议python 函数中用可变参数

SuperOps 332

前言:

现时姐妹们对“python可变函数”大致比较注重,看官们都需要了解一些“python可变函数”的相关知识。那么小编也在网络上收集了一些有关“python可变函数””的相关内容,希望兄弟们能喜欢,你们一起来了解一下吧!

题目分析

这是一个关于 Python 函数默认参数的「陷阱」的典型示例。在 Python 中,函数的默认参数仅计算一次,而非每次调用。这是一个设计上的选择,而不是一个错误。然而,如果该参数是可变的,那么可能会导致一些出乎意料的结果。

在您的例子中,values 参数默认为一个空列表。由于列表是可变的,这意味着当你使用 append​ 方法改变 values​ 时,你是在改变原列表。未来的函数调用将复用已经存在的列表,这可能并不是你所预期的。

可以运行下面的代码理解这个情况:

def f(i, values=[]):    values.append(i)    return values{: id="20231202224435-8gp2xz9" updated="20231202224435"}f(1)  # 输出:[1]f(2)  # 输出:[1, 2],而不是预期的[2]v = f(3)print(v)  # 输出:[1, 2, 3],而不是预期的[3]

为了避免这个问题,最佳实践是将可变的默认参数设置为 None​,然后在函数体内部检查是否应该创建一个新的对象。例如:

def f(i, values=None):    if values is None:        values = []    values.append(i)    return values{: id="20231202224435-vmuf5gw" updated="20231202224435"}f(1)  # 输出:[1]f(2)  # 输出:[2]v = f(3)print(v)  # 输出:[3]

这样,就能够避免因为修改默认参数而导致的潜在问题,使代码更加可靠和明了。

知识点

在Python中,通常不建议将可变对象(例如列表或字典)用作函数的默认参数。这是由于Python函数在定义时,其默认参数的值会被计算,然后这个值被用作后续调用的默认值。这意味着如果你使用可变对象作为默认值,并在函数中更改了它,那么这个改变会影响到后续的函数调用。

让我们以一个简单的例子来解释这个问题:

def add_to(num, target=[]):    target.append(num)    return target

你可能期望每次调用 add_to,都能获取一个新的列表,只包含给定的数值。比如, add_to(1) 返回 [1]。然后,如果你试图再次调用 add_to(2),你可能期望得到 [2],但实际上你会得到 [1, 2]。

原因是 target 列表在函数定义时就已经创建,并且会在每次调用 add_to 函数时被使用。因此,如果你更改了 target 列表,这个改变会保留下来,影响到后续的函数调用。

如果你想每次调用都得到一个新的列表,你可以将默认值设置为 None,然后在函数体里检查它是否为 None 。如果是,那么就创建一个新的列表。

def add_to(num, target=None):    if target is None:        target = []    target.append(num)    return target

在这个版本的 add_to 中,每次调用都会创建一个新的列表作为 target,因此你不再需要担心之前的调用会影响到现在的调用。

如何快速的学习

有人说过,"站在巨人的肩膀上",这种引用同样适用于学习编程,尤其是学习 Python。

在我所经营的技术专栏中,提供了许多 Python 的实战教程,涵盖了从基础知识到深层次的主题。论述是深入浅出、循序渐进的,辅以实战例子和详尽的代码注释,让初学者或者有经验的 Python 程序员都能找到合适自己层次的内容进行学习和参考。

通过跟随我的技术专栏,你可以利用我积累的经验和知识,避开编程初期常见的误区和陷阱,更快地上手 Python。你也无需从无数的教程中摸索寻找有价值的信息,所有你需要的,都在这个专栏中,等你来探索。

不论你是偶尔摸鱼的编程初学者,还是正在寻求提升编程技能的专业开发者,我坚信你都能从我的专栏中收获满满。现在就开始你 Python 之旅吧,我将在你学习的道路上陪伴你。

标签: #python可变函数