SQLite插入失败致Hangman游戏TypeError错误求助
TypeError: 'NoneType' object is not subscriptable 解决思路及修复方案
问题根源
- Cursor使用错误:
get_valid_guessing_word方法中,用新创建的cursor执行查询后,却调用类实例的self.cur去获取结果。两个cursor相互独立,self.cur并未执行当前查询,因此返回None。 - 初始数据未插入:主程序未调用
add_valid_guessing_word方法,导致DICTIONARY表为空,即便cursor逻辑正确,查询也会返回None。 - 无空值判断:获取数据库返回值后直接执行
value[-1],未处理返回None的情况,触发报错。
修复步骤
1. 修正Cursor查询逻辑
修改get_valid_guessing_word方法,使用执行查询的cursor获取结果:
# Get a Record in DB def get_valid_guessing_word(self, id): cursor = self.con.cursor() cursor.execute("SELECT * FROM DICTIONARY WHERE id=?", (id,)) valid_word = cursor.fetchone() # 改为当前cursor调用fetchone() print(valid_word) return valid_word
2. 插入初始单词数据
在主程序初始化Database后,调用插入方法填充数据(新增防重复逻辑避免重复插入):
# 主程序中修改Database初始化部分 db = Database("Goiyala.db") # 在Database类中修改add_valid_guessing_word方法 def add_valid_guessing_word(self): # 先检查表中是否已有数据 self.cur.execute("SELECT COUNT(*) FROM DICTIONARY") count = self.cur.fetchone()[0] if count == 0: for word in self.word_list: self.insert_valid_guessing_word(word) # 调用插入方法 db.add_valid_guessing_word()
3. 增加空值判断避免报错
在newGame函数中,确保获取到有效数据后再执行后续操作:
def newGame(): messagebox.showinfo("Welcome to Hangman","By Roman & Ricario") global the_word_withSpaces global numberOfGuesses global the_word numberOfGuesses = 0 imgLabel.config(image=photos[0]) # 循环获取直到拿到有效数据 value = None while value is None: # 根据word_list长度确定id范围,避免超出实际数据id value = db.get_valid_guessing_word(random.randint(1, len(db.word_list))) the_word = str(value[-1]) print(the_word) the_word_withSpaces = " ".join(the_word) lblWord.set(" ".join("_" * len(the_word)))
4. 优化随机取词方式(可选)
若数据库id可能不连续,可先查询所有单词再随机选择,提升可靠性:
# 在Database类中新增方法 def get_all_valid_words(self): cursor = self.con.cursor() cursor.execute("SELECT WORD FROM DICTIONARY") words = [row[0] for row in cursor.fetchall()] return words # 在newGame中使用该方法 def newGame(): # ... 其他代码 ... word_list = db.get_all_valid_words() if not word_list: messagebox.showerror("Error", "数据库中没有可用单词") return the_word = random.choice(word_list) the_word_withSpaces = " ".join(the_word) lblWord.set(" ".join("_" * len(the_word)))
内容的提问来源于stack exchange,提问作者Ricario Rufus
相关产品推荐
相关产品推荐

