面试题精讲:Python 语言特性
Python 语言特性常以「理解底层逻辑」而非「死记硬背」区分候选人,本文梳理了高频考点,分类整理、删除冗余、突出核心,控制在3000字内。
一、基础变量与作用域
1. 参数传递机制:既非值也非引用,是「传对象引用」
核心结论与道满笔记(保留,太形象了):
- 不可变对象(int/str/tuple):函数内修改会生成新对象,仅改变「临时标签」指向,原变量不受影响
- 可变对象(list/dict/set):直接操作原内存,所有指向该地址的变量都感知
道满笔记: 类型属于对象,变量只是标签。函数复制标签贴过去:贴箱子(可变)掏东西全看见;贴石头(不可变)换个石头贴,原石头标签还在。
2. is vs ==:身份 vs 值
==:调用__eq__比较值is:对比id(),判断是否为同一块内存地址
面试陷阱: Python 会缓存
-5~256的小整数和部分短字符串,超出范围的对象需注意。
3. LEGB 作用域查找规则
从内到外依次查,找不到报错:
- L (Local):当前函数/方法内部
- E (Enclosing):嵌套的外层函数(闭包核心)
- G (Global):当前模块全局
- B (Built-in):Python 内建(如
len/str)
二、核心函数与类
4. 实例/类/静态方法
理解绑定关系是关键:
5. 类变量 vs 实例变量
这是最容易掉的属性查找坑:
- 类变量:所有实例共享(除非显式覆盖),用于计数器、默认配置
- 实例变量:
__init__中初始化,每个实例独有
避坑原则: 除非明确共享数据,否则永远在
__init__里写实例变量。
6. __new__ vs __init__:诞生 vs 装修
__new__:类方法,负责创建实例(返回对象)__init__:实例方法,负责初始化实例(不返回值)
先有
__new__的毛坯房,才有__init__的装修队。
7. Python 3 中的super()
核心意义:维护 MRO 链条,解决多继承(菱形)问题
- Python 3 简化为
super().__init__(),避免硬编码父类 - 根据 C3 算法生成的 MRO 列表(可用
ClassName.mro()查看)调用下一个类的方法,确保每个父类只初始化一次
三、内存管理与性能优化
8. 深/浅拷贝 vs 赋值
处理嵌套对象时的内存管理核心:
- 赋值(
b=a):仅增加标签,完全等价 - 浅拷贝(
copy.copy/切片a[:]):创建新容器,但子对象引用原地址 - 深拷贝(
copy.deepcopy):递归拷贝所有嵌套对象,新老对象完全独立
9. 垃圾回收(GC)机制
引用计数为主,标记清除+分代回收为辅
- 引用计数(主要):每个对象有
ob_refcnt,归零即释放;无法处理循环引用 - 标记清除:解决循环引用,找「不可达根对象」的对象
- 分代回收(优化):基于「活越久越难死」假设,分为0/1/2代,高代检查频率更低
10. 迭代器与生成器:内存友好的懒加载
- 列表:一次性加载所有数据到内存(易爆)
- 生成器:特殊的迭代器,边循环边计算,仅记住当前位置,调用
next()才生成下一个- 生成器函数:用
yield代替return - 生成器表达式:
(x for x in range(1000000))(比列表推导式[]省内存)
- 生成器函数:用
11. Python 3 的range()就是迭代器
(合并原27、30)Python 2中range()返回列表、xrange()是迭代器;Python 3废弃xrange(),现有range()是固定内存的懒加载迭代器,循环百万级数据无压力。
四、Python 3 专属/演进细节
12. 字符串格式化首选 f-string
(合并原8)按速度和可读性排序:
- f-string (Py3.6+):最快、最直观,支持
{}内写表达式和格式化控制 .format():功能强大,支持位置/关键字参数%占位符:古老稳健,但易踩元组参数坑
13. 经典 Python 2 vs 3 差异速查
(合并原27精简版)虽然 Python 2 已淘汰,但面试官常考历史:
print:从语句→print()函数- 编码:默认全 UTF-8,字符串全 Unicode
- 整除:
3/2→1.5(浮点数)
五、高阶特性与设计模式入门
14. 闭包:让函数有「记忆」
定义:内嵌函数引用外层函数变量,且外层返回该内嵌函数,形成闭包
- 关键:即使外层执行完,被引用的变量仍存活在
__closure__属性中 - 应用:装饰器、延迟计算、封装私有变量
15. 装饰器:Python 的 AOP 实现
本质:接收一个函数/类,返回增强版的函数/类,满足开闭原则(不修改原代码,动态加功能)
- 核心场景:日志、权限、缓存、计时
16. 鸭子类型:关注行为而非身份
「走起来像鸭子、叫起来像鸭子,就是鸭子」
- Python 实践:不需要继承特定接口(如
Readable),只要实现read()就可以当文件用 - 优势:代码更灵活、解耦度更高
17. 下划线命名的约定(非强制)
_foo:私有约定,from module import *不导入__foo:名称修饰(变成_ClassName__foo),防止子类覆盖父类属性__foo__:魔术方法,Python 内部定义,开发者不要自定义
18. 元类(简单了解框架即可)
面试常考定义,日常开发少用:
- 类是创建实例的模板,元类是创建类的模板
- 默认元类是
type - 应用:Django ORM、状态机检查(类定义时自动修改行为)
六、补充高频零散考点
19. *args/**kwargs:灵活的参数解包
*args:接收任意位置参数,存为元组**kwargs:接收任意关键字参数,存为字典- 进阶用法:函数调用时解包列表/字典为参数
参数顺序(定义时):普通→
*args→默认→**kwargs
20. 列表/字典推导式
现代 Python 优先用推导式,比map/filter更直观:
- 列表推导式:
[x*2 for x in range(5) if x>2] - 字典推导式(Py2.7+):
{v:k for k,v in {'a':1,'b':2}.items()}
21. 为什么 Python 不需要函数重载?
动态语言特性天然覆盖:
- 参数类型:无需声明,可接收任意类型
- 参数个数:用默认参数、
*args/**kwargs解决
全文完,剩余中高级特性(如 GIL、协程、单例模式)可单独成篇深入探讨。

