Python面试常见问题解析:默认参数与闭包陷阱

需积分: 50 13 下载量 138 浏览量 更新于2024-09-08 收藏 28KB DOCX 举报
"Python面试常见问题与解答" 在Python面试中,经常会有涉及语言特性和最佳实践的问题。这里我们讨论两个经典面试问题及其解决方案。 问题1:默认参数的陷阱 ```python def extendList(val, list=[]): list.append(val) return list list1 = extendList(10) list2 = extendList(123, []) list3 = extendList('a') print("list1=%s" % list1) print("list2=%s" % list2) print("list3=%s" % list3) ``` 在这个例子中,面试官通常会询问这段代码的实际输出,并解释原因。默认参数`list=[]`在函数定义时创建,而不是每次调用时。因此,`list1`和`list3`共享了同一个默认列表,导致它们的结果相同。正确的输出应该是: ``` list1=[10,'a'] list2=[123] list3=[10,'a'] ``` 为了实现预期的行为,我们需要确保每次调用`extendList`时都使用一个新的空列表。可以通过将默认参数改为`None`,并在函数体内检查是否需要创建新列表来实现: ```python def extendList(val, list=None): if list is None: list = [] list.append(val) return list ``` 这样,修改后的代码将产生期望的输出: ``` list1=[10] list2=[123] list3=['a'] ``` 问题2:闭包与延迟绑定 ```python def multipliers(): return [lambda x: i * x for i in range(4)] print([m(2) for m in multipliers()]) ``` 这段代码创建了一个返回四个闭包的列表,每个闭包都引用了外部作用域中的变量`i`。然而,当这些闭包被调用时,它们都使用了`i`的最终值,即3。因此,输出是`[6, 6, 6, 6]`,而不是预期的`[0, 2, 4, 6]`。 这个问题涉及到Python闭包的延迟绑定特性。为了解决这个问题,我们可以使用匿名函数`lambda`的局部作用域,通过创建一个临时的元组来保存每个闭包的`i`值: ```python def multipliers(): return [lambda x, i=i: i * x for i in range(4)] print([m(2) for m in multipliers()]) ``` 通过在`lambda`函数中显式地捕获`i`的当前值,我们可以确保每个闭包都有自己的`i`副本。现在,输出将会是正确的`[0, 2, 4, 6]`。 这两个问题不仅测试了面试者对Python基础语法的理解,还涉及到了高级特性如闭包和默认参数的行为,这些都是Python开发者需要深入掌握的关键概念。在面试中,能够清晰地解释这些问题以及提供修正方案,无疑会展示出对Python的强大理解和实践经验。