1:__slots__ 是什么?它解决什么问题?有什么坑?
回答要点:
__slots__可以限制实例属性集合,避免每个对象都带一个__dict__,从而减少内存占用、提高属性访问性能(在大量小对象场景更明显)。- 常见坑:
- 加了
__slots__后不能随便新增属性(除非 slot 里声明了)。 - 如果类需要弱引用,要在 slots 里加
__weakref__。 - 继承时要小心:子类 slots 叠加规则、以及是否保留父类
__dict__。
- 加了
2:__getattr__ vs __getattribute__ 有什么区别?什么时候会无限递归?
回答要点:
__getattribute__:所有属性访问都会先走它;你在里面写错很容易把对象变成“不可用”。__getattr__:只在正常查找失败(属性不存在)时才会调用,通常更安全。- 无限递归典型原因:在
__getattribute__里又用self.xxx访问属性,触发再次进入__getattribute__。正确写法一般是用object.__getattribute__(self, name)拿底层实现。

3:@property 和 descriptor(描述符)你怎么解释?它们和“方法/字段”到底有什么关系?
回答要点:
@property让你用“访问属性”的语法去调用 getter/setter,本质是descriptor(实现了__get__/__set__/__delete__的对象)。- 你需要讲清楚的一点:Python 里“属性访问”不是直接读字段,可能触发 descriptor、
__getattribute__、甚至动态计算。 - 追问点:
@property适合做校验/惰性加载/只读字段,但别把重计算塞进去(会让属性访问变成隐藏的慢操作)。
4:global 和 nonlocal 的区别?闭包变量到底存在哪?
回答要点:
global:声明变量来自模块全局作用域。nonlocal:声明变量来自最近一层的外部函数作用域(闭包)。- 追问点:为什么要有
nonlocal?因为闭包里对外层变量赋值默认会创建局部变量,nonlocal才能修改外层绑定。
5:__hash__ 和 __eq__ 的契约是什么?为什么“自定义对象当 dict key”经常出问题?
回答要点:
- 作为 dict key / set 元素必须是 hashable:
hash(x)在对象生命周期内要稳定。 - 关键契约:如果
a == b,那么必须hash(a) == hash(b),否则哈希容器行为就会错(查不到、重复、丢失等)。 - 常见坑:你重写了
__eq__但没重写__hash__,Python 会把它变成不可 hash(防止你误用)。
6:dataclass/namedtuple/普通类 怎么选?你怎么解释它们的取舍?
回答要点:
dataclass:快速生成__init__/repr/eq等,适合“数据载体”;配合frozen=True可做不可变值对象。namedtuple:更轻、更偏“tuple 语义”,适合只读小结构、需要解包/位置语义的场景。- 普通类:当你需要复杂行为、校验、继承、多态时更合适。
- 追问点:
dataclass的默认可变字段坑(例如 list 默认值)要用default_factory。
7:Python 的 import 机制?循环导入怎么破?
回答要点:
- import 会先查
sys.modules缓存;同一个模块只会初始化一次,后续是复用引用。 - 循环导入常见表现:属性不存在、模块处于“半初始化状态”。
- 解决思路:
- 拆分公共依赖到第三个模块
- 延迟导入(在函数内部 import)
- 调整依赖方向(让底层模块不 import 上层模块)
8:logging 怎么用才算“线上可排障”?不要只说“我会 print”
回答要点:
- 线上日志至少要能回答三件事:谁(trace/request id)、在哪(模块/函数)、发生了什么(结构化字段)。
- 常见落地:
- 用
logging的 logger 分级(INFO/WARN/ERROR),不要全用 print。 - 异常用
logger.exception(...)保留堆栈。 - 关键链路打点要“结构化”(字段化),便于检索聚合(而不是拼接大长字符串)。
- 用
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/misayaaaaa/article/details/157975361



