如何从pickle文件加载对象且不遮蔽外部作用域的同名变量
问题修复
你的猜测是正确的,报错原因就是嵌套函数内操作全局变量未做声明:
Python规则是:如果函数内部对某个变量做了赋值操作,默认会把这个变量识别为当前函数的局部变量。你在menu函数的读档分支给cubicles、marciaOffice、bossOffice做了赋值,所以Python会把这三个变量当成menu的局部变量:
- 存档分支读取这三个变量时,局部变量还没赋值,就抛出
local variable 'cubicles' referenced before assignment错误 - 读档分支的局部变量和外层全局变量同名,就会触发
shadows name 'cubicles' from outer scope的警告
修复只需要在menu函数的最开头添加全局变量声明即可:
def menu(): global cubicles, marciaOffice, bossOffice, currentRoom # 后面保留你原来的menu逻辑即可
实用改进建议
- 修正条件判断错误:你写的
if ("advance" and "all") in response逻辑是错误的,"advance" and "all"的运算结果只有"all",相当于只判断了all是否存在,正确写法是if "advance" in response and "all" in response,("menu" or "pause")的判断同理修改为"menu" in response or "pause" in response。 - 替换递归流程为循环流程:你现在的逻辑是
game()→decisionTree()→menu()→game()循环调用,运行次数多了会触发Python递归深度上限报错,建议用死循环包裹游戏主逻辑,用分支控制流程跳转,不要反复嵌套调用函数。 - 封装游戏状态统一管理:不要零散定义多个全局变量存房间、当前位置,建议把所有游戏状态封装到一个
GameState类里,存读档只要序列化这个类的实例即可,不用分别dump/load多个对象,后续新增状态也不用改存读档逻辑,示例:
class GameState: def __init__(self): self.cubicles = Room(0, "your cubicle", "It's a room full of cubicles. You can go to Marcia's Office or your Boss's Office.") self.marciaOffice = Room(0, "Marcia's office", "It's a small office where Marcia works. You can go to the cubicles or your Boss's Office.") self.bossOffice = Room(0, "your Boss's office", "This is where your boss works. You can go to the cubicles or Marcia's Office.") self.current_room = self.cubicles
- 补全读档逻辑:你当前读档只更新了三个房间对象,没有更新
currentRoom的指向,读档后当前所在位置还是读档前的位置,会出现逻辑不一致,需要把currentRoom也加入存读档序列。 - 增加存读档异常捕获:给存读档逻辑加
try...except捕获文件不存在、文件损坏、权限不足等异常,给用户友好提示,避免程序直接崩溃。
内容的提问来源于stack exchange,提问作者Dovid EZ Stern
相关产品推荐
相关产品推荐

