3 分钟阅读
lru_cache:缓存结果之前,先确定数据何时过期
给一个读取配置的函数加缓存可以减少重复工作,却也可能让修改后的配置一直不可见。缓存正确性首先取决于结果是否只由键决定。
给一个读取配置的函数加缓存可以减少重复工作,却也可能让修改后的配置一直不可见。缓存正确性首先取决于结果是否只由键决定。
分组代码里反复检查键是否存在很繁琐。defaultdict 可以按需生成容器,但其读取行为也引入了容易忽略的副作用。
集合能回答“是否出现过”,但无法回答出现多少次。日志级别、标签和词频分析通常需要一个从元素到次数的映射。
处理大量记录时,把所有数据先转成列表再切片会占用不必要的内存。分批消费迭代器,可以让内存需求主要受批大小控制。
成绩降序、姓名升序是一条组合规则。如果先把整份排序结果 reversed,同分名字也会被反转,违背预期。
给函数加上 int 注解后,传入字符串并不一定立即报错。类型提示主要服务于工具与阅读者,运行时行为仍由实际代码决定。
订单、任务和配置对象经常带一个列表字段。如果多个实例共享同一容器,对其中一个实例的修改就会污染其他实例。
把所有解析错误改成一句“配置错误”,会让排查者不知道究竟是哪一步失败。异常包装需要同时保留上层语义和底层原因。
把清理动作写在函数末尾,无法覆盖中途抛异常的情况。with 语句把资源作用域放到语法结构里,退出时调用清理协议。
直接通过字符串替换扩展名,可能误改父目录中的相同字符。路径对象提供文件名、后缀和父目录等结构化操作。
价格或成功率显示很多小数时,常用格式化保留两位。要注意格式化产生的是字符串,并没有修正此前运算中的误差。
循环中不断追加分隔符,往往要额外处理最后一个逗号。先构造字段,再由 join 连接,可以让边界规则更清楚。