Python编写词袋函数遇局部变量words赋值前引用报错 试过加global仍未解决
报错排查与修复方案
核心报错原因
- Python 作用域判定规则触发报错:Python 解析器会在函数加载阶段就扫描整个函数块的变量赋值情况,只要某个变量在函数任意位置出现了赋值操作,就会直接把该变量标记为函数局部变量,不会向外查找全局/外层的同名变量。你的代码中内层循环
for i, words in enumerate(words):对words做了循环赋值,直接把原本要引用的词汇表变量words标记为局部变量,导致执行到第一行len(words)时,局部变量还没完成赋值,就抛出local variable 'words' referenced before assignment错误。 - 之前尝试添加
global words无法解决问题的核心逻辑:就算加了全局声明,循环里的赋值操作还是会覆盖全局words的值。第一轮循环就会把enumerate拆出来的单个词汇赋值给words,原本的全局词汇表列表会被替换成单个字符串元素,后续循环遍历words时根本拿不到完整的词汇表,词袋计算逻辑完全失效。 - 代码存在额外笔误:判断条件
if word == w:中的word没有任何定义,就算解决了作用域问题,这行代码仍会触发NameError: name 'word' is not defined的报错。
具体修复步骤
- 解决变量重名冲突:将内层循环的临时变量和要引用的词汇表变量做命名区分,不要使用完全相同的变量名,避免覆盖外层值
- 修正判断条件的笔误,将未定义的
word替换为循环遍历出来的临时词汇变量 - (可选优化)放弃全局变量传值的方式,将词汇表作为函数显式参数传入,从根源减少作用域冲突概率,同时提升函数可测试性
修复后参考代码
推荐写法:将词汇表作为参数传入,降低全局依赖
import numpy as np # 预先整理好的去重词汇表 vocab = ["你预处理完成的所有不重复词汇列表"] def bag_of_words(sentence, vocab): sentence_words = clean_up_sentence(sentence) bag = [0] * len(vocab) for w in sentence_words: for i, vocab_word in enumerate(vocab): if vocab_word == w: bag[i] = 1 return np.array(bag)
如果必须使用全局词汇表,只要保证循环内不对
words做同名赋值,全局声明就可以正常生效,示例如下:import numpy as np # 全局词汇表 words = ["你预处理完成的所有不重复词汇列表"] def bag_of_words(sentence): global words sentence_words = clean_up_sentence(sentence) bag = [0] * len(words) for w in sentence_words: # 把循环内的临时变量改名,不再和全局words重名 for i, vocab_word in enumerate(words): if vocab_word == w: bag[i] = 1 return np.array(bag)
内容的提问来源于stack exchange,提问作者Hitesh Ganga
相关产品推荐
相关产品推荐

