每日一练 Python 面试题(11)

阿里云教程2个月前发布
21 0 0

每日一练 Python 面试题(11)

题 1:闭包(Closure)机制

问题:
请解释以下代码的输出结果,并说明缘由:

def make_adders():
    return [lambda x: x + i for i in range(3)]

adders = make_adders()
print([f(10) for f in adders])

答案:

[12, 12, 12]

解析:
lambda x: x + i 中的 i 是自由变量,在函数返回后并不会立刻绑定,而是在调用时再从外层作用域取值。
循环结束后,i = 2,因此所有 lambda 闭包都引用了同一个最终的 i 值。

修复方式:

return [lambda x, i=i: x + i for i in range(3)]

→ 输出 [10, 11, 12]


题 2:异常处理

问题:
请问以下代码输出什么?为什么?

try:
    print(1)
    raise ValueError("Error")
except Exception:
    print(2)
else:
    print(3)
finally:
    print(4)

答案:

1
2
4

解析:
执行顺序:

  • print(1) → 输出 1
  • 抛出 ValueError → 被 except Exception 捕获 → 输出 2
  • else 块仅在没有异常时执行 → 被跳过
  • finally 总是执行 → 输出 4

题 3:装饰器(Decorator)

问题:
请编写一个装饰器 @timeit,用于统计函数执行耗时。

答案:

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 执行耗时: {end - start:.4f}s")
        return result
    return wrapper

@timeit
def slow_function():
    time.sleep(1)

slow_function()

输出示例:

slow_function 执行耗时: 1.0001s

解析:
装饰器在不修改原函数代码的前提下,增加功能逻辑。这里通过包装函数执行前后的时间差统计运行时间。


题 4:可变对象陷阱

问题:
请解释以下代码的输出结果:

def append_item(item, items=[]):
    items.append(item)
    return items

print(append_item(1))
print(append_item(2))

答案:

[1]
[1, 2]

解析:
函数默认参数 items=[] 只在函数定义时执行一次,因此所有调用共享同一个列表对象。
→ 第二次调用时,列表已包含 [1],再添加 2 后变成 [1, 2]。

正确写法:

def append_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

题 5:多线程与 GIL

问题:
Python 多线程为什么不能真正实现 CPU 并行?多线程在什么情况下依旧有意义?

答案:

  • 缘由:
    Python(CPython)中存在 GIL(Global Interpreter Lock,全局解释器锁),同一时刻只允许一个线程执行 Python 字节码,因此 CPU 密集型任务无法并行。
  • 有意义的场景:
    • I/O 密集型任务(如网络请求、文件读写、数据库操作)
    • 通过多线程可在等待 I/O 时切换执行,提高整体吞吐效率。

✅ CPU 密集型任务可使用 multiprocessing 模块实现真正并行。

© 版权声明

相关文章

暂无评论

none
暂无评论...