Python自动售货机代码遇两类错误:'open'未定义与AttributeError
自动售货机重构后两类错误的修复方案
错误1:输入"Stocki"触发"name 'open' is not defined"异常
问题描述
输入正确位置"Stocki"时,程序抛出NameError: name 'open' is not defined异常。
原因分析
原代码在类的__del__()方法中调用open函数保存数据,但Python解释器关闭时,内置函数可能已被提前销毁,导致__del__执行时无法找到open。
修复方案
使用atexit模块注册退出回调函数,替代__del__方法处理程序退出时的保存操作:
- 导入
atexit模块 - 在类初始化时,用
atexit.register()注册保存数据的方法 - 删除原有的
__del__方法
修改后代码片段
import atexit import json class VendingMachine: def __init__(self, name): self.name = name # 注册退出时的保存操作 atexit.register(self.save_data) def save_data(self): # 原__del__中的保存逻辑移到这里 with open(f"{self.name}_data.json", "w") as f: json.dump({"name": self.name}, f)
错误2:先输错误值再输"Stocki"触发"AttributeError: 'NoneType' object has no attribute 'get_name'"
问题描述
先输入错误位置值,再输入正确的"Stocki"时,程序抛出AttributeError,提示NoneType没有get_name方法。
原因分析
递归函数set_vending在异常处理分支中,没有返回递归调用的set_vending()结果,导致函数返回None,后续代码调用get_name()时出错。
修复方案
在异常处理块中,返回递归调用set_vending()的结果,确保无论成功还是异常递归,函数都能返回有效的实例对象。
修改前错误代码片段
def set_vending(): try: location = input("Enter location: ") if location != "Stocki": raise ValueError("Invalid location") return VendingMachine(location) except ValueError as e: print(e) set_vending() # 这里没有返回,导致函数返回None
修改后正确代码片段
def set_vending(): try: location = input("Enter location: ") if location != "Stocki": raise ValueError("Invalid location") return VendingMachine(location) except ValueError as e: print(e) return set_vending() # 添加return,确保返回实例
完整示例代码
import atexit import json class VendingMachine: def __init__(self, name): self.name = name atexit.register(self.save_data) def get_name(self): return self.name def save_data(self): data = {"location": self.name} with open(f"{self.name}_config.json", "w") as f: json.dump(data, f) def set_vending(): try: location = input("Enter location: ") if location != "Stocki": raise ValueError("Location must be 'Stocki'") return VendingMachine(location) except ValueError as e: print(f"Error: {e}") return set_vending() if __name__ == "__main__": vm = set_vending() print(f"Vending machine initialized at: {vm.get_name()}")
配套JSON配置示例(Stocki_config.json)
{ "location": "Stocki" }
内容的提问来源于stack exchange,提问作者Muddyblack k
相关产品推荐
相关产品推荐

