解包map迭代器时触发TypeError: 'int'对象不可迭代的原因排查
问题定位与修复方案
让我来帮你拆解这个问题的根源——你遇到的TypeError: 'int' object is not iterable,其实是FlatClass的逻辑缺陷和后续itertools.chain的要求不匹配导致的,我们一步步来梳理:
触发错误的完整执行流程
当你调用flatten(1, [2])时,整个执行链路是这样的:
print_io包装的outty函数先处理入参:args = deiter(args)- 对于
1:contains_iter(1)返回False,所以deiter直接返回1 - 对于
[2]:contains_iter([2])返回True,递归处理后返回(2,)
最终处理后的args是(1, (2,))
- 对于
- 调用
FlatClass()(1, (2,))进入__call__方法:- 因为参数数量大于1,执行
args = map(self, args),也就是分别把1和(2,)传给FlatClass实例:- 处理
1:进入__call__后,尝试iter(1)触发TypeError,于是直接返回1(这个int值) - 处理
(2,):成功转为迭代器并返回
- 处理
- 接下来执行
r = itertools.chain(*args)——这里解包map迭代器后,相当于chain(1, <迭代器>),但itertools.chain要求每个参数都是可迭代对象,1是int不可迭代,直接触发你看到的TypeError
- 因为参数数量大于1,执行
- 异常被
print_io捕获并转为字符串,但这已经是错误发生后的补救流程了。
核心问题点
FlatClass.__call__在处理单个非可迭代参数(比如int)时,直接返回参数本身,而不是包装成可迭代对象,导致后续chain无法处理。contains_iter存在潜在bug:比如单字符字符串会被误判为不包含迭代器(因为elem == cont会触发跳出),不过这不是当前问题的直接诱因。
修复方案
1. 修正FlatClass.__call__的返回逻辑
当遇到单个非可迭代参数时,把它包装成单元素的可迭代对象(比如元组的迭代器),这样chain就能正常处理:
class FlatClass: def __call__(self, *args): try: if len(args) <= 1: try: # 尝试将参数转为迭代器 r = iter(args[0]) except BaseException: # 处理空参数或非可迭代参数,包装成可迭代对象 if not args: r = tuple() else: # 把单个非可迭代值包装成单元素元组的迭代器 r = iter((args[0],)) else: args = map(self, args) r = itertools.chain(*args) except IndexError: r = tuple() # 处理空参数的 fallback finally: pass return r
2. 优化contains_iter函数(可选)
修复单字符字符串的误判问题,同时排除字符串(如果你不想把字符串当成递归容器处理的话):
def contains_iter(cont): """ returns true if container is an iterator or if container contains an iterator (recursively) """ # 排除字符串,避免把单个字符当成容器递归 if isinstance(cont, str): return False range_type = type(range(1)) # 先判断是否是迭代器或range对象 if hasattr(cont, "__next__") or isinstance(cont, range_type): return True try: # 尝试获取迭代器,判断是否可迭代 it = iter(cont) for elem in it: if contains_iter(elem): return True return False except TypeError: # 对象不可迭代 return False
修复后的测试结果
调用flatten(1, [2])后,会得到正常输出:
######################################## flatten(1, (2,)) OUTPUT: (1, 2) ########################################
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

