iterable与subscriptable的区别是什么?是否存在仅属于其中一类的对象?
subscriptable对象与iterable对象的核心区别
- subscriptable(可下标访问)对象:核心判定标准是实现了
__getitem__()魔法方法,支持通过obj[key]语法访问内容,key可以是整数、字符串、切片等任意自定义的合法类型。你之前的认知存在偏差:subscriptable不要求内部存储其他对象,只要支持[]访问即可,比如你可以自定义一个__getitem__动态计算返回值,内部没有存储任何元素也属于subscriptable。 - iterable(可迭代)对象:核心判定标准是实现了
__iter__()魔法方法,或者实现了参数接收从0开始递增整数的__getitem__()方法,支持被for循环遍历、可以传入iter()生成对应迭代器。你之前对迭代器的认知完全错误:迭代器本身不属于subscriptable对象,迭代器仅要求实现__iter__()和__next__()方法,没有强制要求支持下标访问。
属于subscriptable但不属于iterable的对象
这类对象比较少见,大多是自定义的特殊类,比如仅支持字符串键访问、不支持整数键也没有实现__iter__()的类,示例如下:
class CustomSubscriptable: def __getitem__(self, key): if isinstance(key, str): return f"对应key:{key}的返回值" raise KeyError("仅支持字符串类型的key")
该类的实例可以执行obj["name"]获取返回值,但执行for item in obj会直接抛出类型错误,因为既没有__iter__()方法,__getitem__()也不支持从0开始的整数参数,不属于可迭代对象。
属于iterable但不属于subscriptable的对象
这类对象非常常见,典型代表包括:
- 集合
set:支持for循环遍历所有元素,但因为是无序存储结构,没有实现__getitem__(),无法通过下标访问元素 - 所有迭代器对象:比如
iter([1,2,3])返回的列表迭代器,支持遍历但调用it[0]会报错 - 生成器对象:包括生成器表达式
(i for i in range(5))、yield关键字定义的生成器函数返回的对象,仅支持遍历,不支持下标访问 map、filter、zip等内置高阶函数返回的对象- 打开的文件句柄:可以逐行迭代读取内容,但无法通过下标获取指定行
内容的提问来源于stack exchange,提问作者Aashutosh Ranjan
相关产品推荐
相关产品推荐

