Python 面试 · 语言基础
高频问法
- 可变与不可变类型?
- 列表推导式、字典推导式注意什么?
- 函数默认参数为什么别用可变对象?
is和==区别?- 装饰器怎么理解?能写个简单的吗?
- 迭代器与生成器?
- 上下文管理器
with解决什么? *args/**kwargs/ 解包?
口述参考
1)可变 / 不可变
- 不可变:
int、str、tuple等——「改」往往是生成新对象。 - 可变:
list、dict、set——原地可改。
影响:当字典 key、当默认参数、多处共享引用时的坑。
2)推导式
写法短,但别嵌太深;有副作用(写文件、请求)时用显式循环更清晰。
大列表推导可能一次性占内存,必要时用生成器表达式 (x for x in …)。
3)默认参数陷阱
python
def append_to(item, bucket=[]): # 错误示范:默认 list 只创建一次
bucket.append(item)
return bucket正确:bucket=None,函数里 if bucket is None: bucket = []。
4)is vs ==
== 比值;is 比是否同一对象。
判空常用 is None,不要 == None 当风格问题也可提。
5)装饰器(口述 + 能写更好)
本质:接收函数、返回函数。
用途:日志、鉴权、重试、计时。
带参数的装饰器是「三层」:最外层收参数,中间收函数,内层收调用。
6)迭代器 / 生成器
迭代器:实现 __iter__ / __next__。
生成器:函数里 yield,自动做成迭代器,懒计算、省内存。
7)with
保证资源释放(文件、锁、连接)。with open(...) as f 离开代码块会关文件,比手写 close 稳。
8)解包
a, b = pair;*rest 收集剩余;传参 func(*args, **kwargs) 拆开传入。
追问预备
- 「
__init__和__new__?」→ 知道__new__创建实例、__init__初始化即可,不深抠除非岗位偏 Python。 - 「鸭子类型?」→ 不看继承看行为(有该方法就能用);和 Java 强类型对比一嘴。