python这几个内置标准库,不用额外安装却强的可怕

python的强大众所周知

我们使用 python 的开发者,除了因为它在世界上非常火爆,训练 ai 还得学它,更重要的一点其实应该是它庞大的社区,丰富的第三方库资源。

现在几乎任何领域,都能在 python 的 pypi 上找到相应的第三方库,如果你是办公室白领,openxyl 可以为你带来强大的 excel 自动化处理能力;如果你是力学结构,那么 scipy 可以提供丰富的算法;如果你是机器视觉方面工作者,opencv-python 可以为你完成绝大部分工作……

本篇文章不讨论需要安装的 第三方库,而是来宣传宣传那些比较冷门的、不常见的,但十分强大的 python 内置标准库。

1. contextlib

contextlib 为涉及 with 相关的语法提供了更加实用的一些工具。

1.1 suppress

我们先来看一个场景,当需要读取一个 可能不存在 的文件时,我们会这么操作:

普通代码
try:
    with open('test.txt', 'r') as f:
        f.read()
except FileNotFoundError:
    pass

接下来看 suppress() 来如何高效操作:

suppress 代码
from contextlib import suppress

with suppress(FileNotFoundError):
    with open('test.txt', 'r') as f:
        f.read()

suppress() 将捕获异常,不需要写长串的 try 块代码。

1.2 contextmanager

如果我们需要实现自己的 with 上下文管理,普通情况是这么写:

普通代码
class MyOpen:
    def __init__(self, path='', mode='w'):
        self.file = open(path, mode)

    def __enter__(self):
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

with MyOpen('test.txt', 'r') as f:
    f.read()

这个方式需要创建一个  来实现,现在换成 contextmanager 来实现一个 with :

contextmanager 代码
from contextlib import contextmanager


@contextmanager
def my_open(path='', mode='w'):
    file = open(path, mode)
    try:
        yield file
    finally:
        file.close()


with my_open('test.txt', 'r') as f:
    f.read()

2. itertools

itertools 是为了高效循环而创建迭代器的模块。

2.1 permutations

permutations() 可以获取全部排列,我们先来看一个普通代码示例。

我希望获得 1、2、3 三个数字的全部组合,我们会这么写:

普通代码
def get_permutations(nums):
    # 如果列表为空,返回空列表
    if not nums:
        return []

    # 如果列表只有一个元素,返回该元素本身
    if len(nums) == 1:
        return [nums]

    # 用于存储所有排列的结果
    result = []

    # 遍历列表中的每个元素
    for i in range(len(nums)):
        # 当前元素
        current_num = nums[i]

        # 剩余元素
        remaining_nums = nums[:i] + nums[i + 1:]

        # 递归获取剩余元素的排列
        for perm in get_permutations(remaining_nums):
            # 将当前元素与剩余元素的排列组合
            result.append([current_num] + perm)

    return result


num_list = [1, 2, 3]
results = get_permutations(num_list)
for res in results:
    print(res)

可以看到简单的需求实现起来却非常复杂,现在换成 permutations() 来实现:

permutations 代码
from itertools import permutations


num_list = [1, 2, 3]
results = permutations(num_list)
for res in results:
    print(res)

注意:itertools 的返回是迭代器,需要用迭代器的方法获取内容。

2.2 cycle

或许在日常工作中,你经常需要无限循环一个数列,例如 A、B、C、A、B、C、A、B、C…… ,这个在正常开发中会这么写:

普通代码
import time

words = ['A', 'B', 'C']

current_index = 0
while True:
    word = words[current_index]
    print(word)
    current_index += 1

    if current_index >= len(words):
        current_index = 0

    time.sleep(1)

现在我们有了更方便的选择:cycle。它的代码如下:

cycle 代码
from itertools import cycle
import time

words = ['A', 'B', 'C']

cycle_seq = cycle(words)
while True:
    word = next(cycle_seq)
    print(word)

    time.sleep(1)

3. argparse

在很多时候,我们开发的 python 工具都不是 可视化产品,更多的是 命令行工具,这样可以省去很多工作。

如果我们有个脚本工具可以使用命令行执行,它可以展示版本号功能和填一个数字 计算加上5之后的和,我们可以这样写:

普通代码
import sys

if __name__ == '__main__':
    if '-v' in sys.argv or '--version' in sys.argv:
        print('v3.1')
    elif '-add' in sys.argv:
        index = sys.argv.index('-add') + 1
        try:
            num = int(sys.argv[index])
            print(5 + num)
        except Exception as e:
            print('没有数字')
调用脚本
# 查看版本
python tool.py -v

# 计算 10 + 5 的和
python tool.py -add 10

这里需要我们去处理很多东西,非常复杂,现在换为 argparse 来试一下:

argparse 代码
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        prog='项目',
        description='这个项目用来测试',
        epilog='这里是帮助语句底部内容'
    )
    parser.add_argument('-v', '--version', action='store_true', help='查看版本')
    parser.add_argument('-add', '--add', type=int, help='计算加5的和')

    args = parser.parse_args()

    if args.version:
        print('v3.1')

    if args.add:
        print(5 + args.add)

调用方法与上面一致,写法却更加优雅,甚至还额外默认提供了 -h 帮助信息查看,让我们可以调用:

python tool.py -h

返回内容如下:

usage: 项目 [-h] [-v] [-add ADD]

这个项目用来测试

options:
  -h, --help           show this help message and exit
  -v, --version        查看版本
  -add ADD, --add ADD  计算加5的和

这里是帮助语句

4. bisect

二分查找法 是非常实用的方法,可以快速定位,如果我们需要自己去实现。

现在有个需求是有个列表 [{'id': 1}, {'id': 2}, {'id': 6}, {'id': 8}] ,它是有序的,现在要插入一个 {'id': 3} 到列表中:

普通代码
def binary_search_right(arr, target):
    left, right = 0, len(arr)
    while left < right:
        mid = (left + right) // 2
        if arr[mid]['id'] <= target:
            left = mid + 1
        else:
            right = mid
    return left


dicts = [{'id': 1}, {'id': 2}, {'id': 6}, {'id': 8}]
data = {'id': 3}
# 获取插入的位置
index = binary_search_right(dicts, data['id'])
print(index)

实现的代码还是比较复杂的,现在来看 bisect 的功力:

bisect 代码
from bisect import bisect_right

dicts = [{'id': 1}, {'id': 2}, {'id': 6}, {'id': 8}]
data = {'id': 3}

ids = [item['id'] for item in dicts]
index = bisect_right(ids, data['id'])
print(index)

结尾

今天我们介绍了四款不常用但非常强大的内置标准库,它们不需要额外进行 pip 安装就可 开袋即食

当然还有许多强大的 内置标准库,你还知道哪些,快来留言告诉我吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python卡皮巴拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值