You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为生成对象分块的Python chunks函数添加正确类型提示?

正确为chunks函数添加类型提示的方案

要解决这个函数的类型提示问题,我们需要利用Python的泛型TypeVar和可调用类型提示,来适配cls参数既可以是集合类型构造器(如list、tuple、dict)又可以是返回集合的函数(如sorted)的场景。

完整带类型提示的代码

from typing import Iterable, TypeVar, Callable, Iterator
import itertools

# 定义元素类型的泛型变量
Item = TypeVar('Item')
# 定义集合类型的泛型变量,绑定到包含Item的可迭代类型
CollectionType = TypeVar('CollectionType', bound=Iterable[Item])

def chunks(
    iterable: Iterable[Item],
    chunk_size: int = 10,
    cls: Callable[[Iterable[Item]], CollectionType] = list
) -> Iterator[CollectionType]:
    _iter = iter(iterable)
    while True:
        values = cls(itertools.islice(_iter, chunk_size))
        if not values:
            break
        yield values

关键部分解释

  1. 泛型变量定义

    • Item:用来追踪输入迭代器中元素的具体类型(比如int、str、tuple[K, V]等),让类型检查器能正确推断各场景下的元素类型。
    • CollectionType:绑定到Iterable[Item],确保cls返回的集合是可迭代的(这样if not values的空值检查才合法),同时关联集合内的元素类型为Item。
  2. cls参数的类型提示

    • 使用Callable[[Iterable[Item]], CollectionType]:表示cls是一个可调用对象(可以是类构造器,比如list;也可以是普通函数,比如sorted),它接受一个包含Item类型元素的迭代器,返回CollectionType类型的集合。默认值list完全符合这个签名,因为list构造器本身就接受迭代器并返回列表。
  3. 返回值类型提示

    • 函数是生成器,所以返回Iterator[CollectionType]:表示生成器会逐个产出CollectionType类型的集合,类型检查器会根据传入的cls自动推断具体的集合类型(比如list[int]、tuple[str]、dict[int, int]等)。

验证你的示例场景

我们可以确认这个类型提示能完美适配你给出的所有用法:

  • list(chunks(range(5), chunk_size=3)):类型推断为list[list[int]],正确。
  • list(chunks((x for x in range(5)), chunk_size=3, cls=tuple)):类型推断为list[tuple[int]],正确。
  • list(chunks('qwertyasdfgh', chunk_size=3, cls=sorted)):类型推断为list[list[str]],正确。
  • list(chunks({x: x**2 for x in range(5)}.items(), chunk_size=3, cls=dict)):类型推断为list[dict[int, int]],正确。

注意事项(Python版本兼容)

如果你使用Python 3.9及以上版本,可以直接使用标准库的原生泛型(比如list[Item]、tuple[Item]),无需从typing模块导入Iterable,代码可以简化为:

from typing import TypeVar, Callable, Iterator
import itertools

Item = TypeVar('Item')
CollectionType = TypeVar('CollectionType', bound=Iterable[Item])

def chunks(
    iterable: Iterable[Item],
    chunk_size: int = 10,
    cls: Callable[[Iterable[Item]], CollectionType] = list
) -> Iterator[CollectionType]:
    _iter = iter(iterable)
    while True:
        values = cls(itertools.islice(_iter, chunk_size))
        if not values:
            break
        yield values

内容的提问来源于stack exchange,提问作者Alexander Myskin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:17:47