page contents

Python老手都在偷用:不装任何第三方包,标准库藏了10个神仙功能

写Python代码久了会发现一个现象。很多功能标准库直接给了答案。大多数人没翻过文档。遇到问题第一反应是装第三方包。装完包还要读它的文档。时间花了两遍。标准库里的东西用熟了能省掉一半依赖。

attachments-2026-09-GmAKG8WL6ab7234f83565.png写Python代码久了会发现一个现象。很多功能标准库直接给了答案。大多数人没翻过文档。遇到问题第一反应是装第三方包。装完包还要读它的文档。时间花了两遍。标准库里的东西用熟了能省掉一半依赖。

路径操作

拿路径操作来说。刚学Python的人喜欢用字符串拼接。path = folder + '/' + filename。这种写法在Linux上跑得通。换到Windows就出问题。斜杠方向不一样。正确做法是导入pathlib。p = Path(folder) / filename。这个除法运算符被重载过。专门用来拼路径。跨平台不需要改代码。p.exists()判断文件在不在。p.suffix拿扩展名。p.stem拿不带扩展名的文件名。p.parent往上走一层。这些方法比os.path系列短。读起来也更顺。

文件读写

文件读写也有讲究。很多人写f = open('data.txt', 'r')。然后手动f.close()。中间如果抛异常,close不会执行。文件句柄就泄漏了。标准写法是用with。with open('data.txt', 'r', encoding='utf-8') as f:。缩进块结束自动关闭。不用管异常。encoding参数最好每次写。不写的话用系统默认编码。Windows上默认GBK。读一个UTF-8文件就乱码。这个坑踩过的人不少。

字典技巧

字典取值有个细节。d = {'a': 1}。想拿b的值。d['b']直接报KeyError。很多人写if 'b' in d: value = d['b'] else: value = 0。三行代码。用d.get('b', 0)一行搞定。第二个参数是默认值。不传默认返回None。还有一个更冷门的d.setdefault('b', [])。键存在就返回原值。键不存在就插入默认值再返回。处理嵌套数据结构的时候特别顺手。比如按某个字段分组。groups = {}。循环里写groups.setdefault(key, []).append(item)。不需要先判断键在不在。

推导式细节

列表推导式大家都会用。[x*2 for x in range(10)]。加条件也简单。[x for x in data if x > 0]。嵌套循环也能写。[(i,j) for i in a for j in b]。但有个性能点很少人注意。推导式里的条件判断如果依赖一个函数调用。每次循环都会调。[x for x in data if is_valid(x)]。is_valid被调N次。可以先做一次过滤。valid_data = filter(is_valid, data)。然后[x for x in valid_data]。效果一样。可读性看个人习惯。

生成器

生成器跟列表长得像。区别在方括号换圆括号。(x*2 for x in range(10))。列表一次性把所有元素算出来放内存。生成器算一个吐一个。处理大文件的时候差别巨大。读一个10G的日志。lines = open('huge.log')。这个lines就是生成器。逐行读。内存占用稳定。写成lines = open('huge.log').readlines()就完了。整个文件进内存。机器直接卡死。判断一个对象是不是生成器可以用inspect.isgenerator。日常写代码用yield就能造生成器。函数里出现yield,调用它不执行函数体。返回一个生成器对象。下次next()才跑到第一个yield。

装饰器实战

装饰器被讲烂了。实际项目里最有用的场景是计时和重试。写一个计时装饰器。def timer(func): def wrapper(*args, **kwargs): start = time.time(); result = func(*args, **kwargs); print(f'{func.__name__} took {time.time()-start:.2f}s'); return result; return wrapper。套在函数上面@timer。调用时自动打印耗时。重试装饰器更实用。网络请求偶尔失败。写一个@retry(max_attempts=3)。内部用for循环加try except。失败就睡一会儿再试。成功就返回。超过次数抛异常。这两个装饰器加起来不到二十行。省掉一堆重复代码。

异常处理

异常处理有个常见错误。try: do_something() except: pass。裸except会吞掉所有异常。包括键盘中断和系统退出。调试的时候什么错都看不到。正确写法是捕获具体异常。except ValueError as e:。拿不到具体类型就至少写except Exception as e:。然后把e打印出来。还有finally块。不管有没有异常都执行。用来释放资源。用with语句其实自动处理了。不需要手动写finally。

字符串格式化

字符串格式化现在有三种方式。百分号%s是老古董。format方法'{}'.format(x)用的人多。f-stringf'{x}'是Python3.6之后加的。性能最好。可读性也最高。f-string里可以写表达式。f'{a+b}'。可以调函数。f'{name.upper()}'。可以指定格式。f'{pi:.2f}'保留两位小数。f'{num:,}'加千分位逗号。这些在报表输出里很省事。有一个细节。f-string里的引号不能跟外面冲突。外面双引号里面就用单引号。反过来也行。

性能测试

说到性能。有个内置模块叫timeit。用来测小段代码的执行时间。命令行里直接跑。python -m timeit -s 'data = list(range(1000))' 'sum(data)'。-s是初始化语句。后面跟要测的代码。它会自动跑多次取平均值。比手动写time.time()准。写代码的时候如果纠结两种写法哪个快。用timeit跑一下就有答案。不要凭感觉猜。字符串拼接用join比+快。这个结论在timeit里跑一次就记住。

collections模块

最后提一个collections模块。里面的Counter统计频率特别方便。Counter('abracadabra')直接返回每个字符出现次数。most_common(3)拿前三名。defaultdict跟普通字典区别是键不存在时自动创建默认值。dd = defaultdict(list)。然后dd['missing'].append(1)不会报错。deque是双端队列。左边右边都能快速添加删除。做广度优先搜索的时候用deque比list快很多。这些工具都在标准库里。导入就能用。不需要pip install。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2440 篇文章

作家榜 »

  1. Pack 2440 文章
  2. 轩辕小不懂 2403 文章
  3. 小柒 2228 文章
  4. Nen 576 文章
  5. 王昭君 216 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章