使用find_job_titles包触发StopIteration错误求助
问题:调用find_job_titles的findall方法触发RuntimeError: generator raised StopIteration
我运行以下代码:
from find_job_titles import FinderAcora finder = FinderAcora()
finder.findall('IT Audit & Governance')
每次都会抛出如下错误:
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) /usr/local/lib/python3.8/dist-packages/find_job_titles/__init__.py in longest_match(matches) 48 """ ---> 49 longest = next(matches) 50 StopIteration: The above exception was the direct cause of the following exception: RuntimeError Traceback (most recent call last) 1 frames <ipython-input-31-5b965ac3d7be> in <module> ----> 1 finder.findall('IT Audit & Governance') /usr/local/lib/python3.8/dist-packages/find_job_titles/__init__.py in findall(self, string, use_longest) 82 else return all overlapping matches 83 :returns: list of matches of type `Match` ---> 84 """ 85 return list(self.finditer(string, use_longest=use_longest)) 86 RuntimeError: generator raised StopIteration
我尝试查找相关解决建议,但问题仍未解决。
解决方案
这个错误的根源是find_job_titles库的longest_match函数在处理无匹配结果的场景时,直接调用next(matches)触发StopIteration异常,而Python 3.7及以上版本会将生成器内部抛出的StopIteration转换为RuntimeError。
以下是几种可行的解决方式:
1. 修改库源码修复逻辑
找到find_job_titles安装目录下的__init__.py文件,定位到longest_match函数(大约在第49行),添加对空生成器的捕获处理:
def longest_match(matches): """ Find the longest match from an iterator of (start, end, value) matches. If multiple matches have the same length, the first one is returned. """ try: longest = next(matches) except StopIteration: return None # 无匹配时返回None,后续逻辑会处理为空列表 for match in matches: if (match[1] - match[0]) > (longest[1] - longest[0]): longest = match elif (match[1] - match[0]) == (longest[1] - longest[0]): if match[0] < longest[0]: longest = match return longest
修改后,当输入文本没有匹配的职位头衔时,函数会返回None,不会触发异常,findall最终会返回空列表。
2. 在业务代码中做兼容处理
不修改库源码的情况下,先通过finditer获取所有匹配结果,再自行处理最长匹配逻辑:
from find_job_titles import FinderAcora finder = FinderAcora() # 先获取所有匹配(关闭最长匹配模式) all_matches = list(finder.finditer('IT Audit & Governance', use_longest=False)) def get_longest_match(matches): if not matches: return [] # 找出长度最长的匹配,长度相同取最先出现的 longest = max(matches, key=lambda m: (m.end() - m.start(), m.start())) return [longest] # 最终结果 result = get_longest_match(all_matches) if all_matches else [] print(result)
3. 临时降级Python版本(不推荐)
如果暂时无法修改代码或库,可以降级到Python 3.6及以下版本——这些版本不会将生成器内的StopIteration转为RuntimeError,但这只是临时 workaround,不建议长期使用。
内容的提问来源于stack exchange,提问作者Phong Lê Quang Chấn
相关产品推荐
相关产品推荐

