Python Higher-Lower游戏跨模块导入列表重初始化未重置问题
问题原因
两个核心Python机制导致你遇到这个bug:
- 模块导入缓存机制:Python对同一个模块只会执行一次导入加载,后续所有重复的导入语句只会直接返回内存中已经缓存的模块对象,不会重新执行模块代码生成新的初始数据。你在游戏过程中直接修改了导入的
data列表,后续重复写from game_data_test import data根本拿不到未修改的初始列表。 - 引用赋值特性:你写的
new_items = data没有创建新列表,只是给内存中同一个列表对象绑定了新变量名,后续对new_items调用remove删除元素时,本质就是在修改导入的原始data列表本身。 - 额外隐患:你用递归调用
game()实现重启,多次重启后会出现函数栈溢出问题。
修复方案
- 只在文件最顶部保留一次
from game_data_test import data导入语句,删掉游戏逻辑里所有重复的导入代码,重复导入没有任何实际作用。 - 每次启动新游戏对局时,基于原始
data生成一份完全独立的副本作为当前局的操作数据源,所有删除操作只作用在副本上,永远不修改原始导入的data对象,这样每局开始拿到的都是完整的初始数据。 - 用外层循环替代递归实现游戏重启,避免栈溢出问题。
修复后完整代码
#Higher-Lower Game Project import random # 仅顶部导入一次原始数据,全程不修改这个对象 from game_data_test import data def game(): print("Welcome to the 'Higher-Lower' game!") # 外层循环控制游戏重启 while True: # 每局开始生成原始数据的独立副本 new_items = [entry.copy() for entry in data] round_number = 1 streak = 0 status = "win" def influencer_selection(): number_influencers = len(new_items) influencer_index = random.randint(0, number_influencers-1) selected_influencer = new_items[influencer_index] new_items.remove(selected_influencer) return selected_influencer def influencer_info(influencer_code): return (f"{influencer_code['name']}, a {influencer_code['description']}, from {influencer_code['country']}.") influencer_a = influencer_selection() influencer_a_info = influencer_info(influencer_a) while status == "win" and len(new_items) > 0: print(f"Round {round_number}:\n\n") influencer_b = influencer_selection() influencer_b_info = influencer_info(influencer_b) print(f"Compare A: {influencer_a_info}") print(f"\nAgainst B: {influencer_b_info}\n") if int(influencer_a['follower_count']) > int(influencer_b['follower_count']): correct_answer = "A" else: correct_answer = "B" answer = input("Who has a higher number of Instagram followers? A or B? \n\n") if answer == correct_answer: print("\nYou're right!") round_number += 1 streak += 1 print(f"\nYou are at {streak} correct guesses!\n") influencer_a = influencer_b influencer_a_info = influencer_b_info else: print("\nOh no, you're wrong!") status = "loss" print(f"\nYou have lost. You had a streak of {streak} correct guesses. Congratulations!\n") break if len(new_items) == 0 and status == "win": print(f"\nCongratulations, you have completed the game with a streak of {streak} correct guesses!\n") again = input("Do you want to play again? 'Y' or 'N'\n\n") if again == "Y": # 直接进入下一轮循环即可,不需要递归调用 continue else: print("\nThank you for playing!") break game()
注:这里用
[entry.copy() for entry in data]生成副本,是因为列表内存储的是字典对象,用推导式复制每个字典生成新列表,就能保证当前局的数据源和原始导入的data完全独立,互不影响。如果后续你不需要修改字典内部的键值对,也可以直接用new_items = data.copy()做列表浅拷贝,效果一致。
内容的提问来源于stack exchange,提问作者AlexE22
相关产品推荐
相关产品推荐

