Python如何通过读写txt文件实现多脚本按状态分支执行
功能可行性结论
该功能完全可以实现,也是文字互动类游戏最常用的跨次启动状态持久化方案,你的核心思路正确,只是现有代码的文件操作和流程逻辑存在几个容易触发bug的细节问题,修正后即可正常运行。
现有代码的核心问题
- 文件操作逻辑存在严重隐患:全局以
r+模式打开文件句柄,用f.seek(2)偏移固定字节读取内容的方式非常脆弱,只要文件内容长度不符合预期就会读错值;另外全局打开的文件默认不会实时把写入内容刷到磁盘,你写完状态立刻杀进程的话,大概率内容还留在内存缓冲区,下次启动根本读不到新写入的章节标识。 - 外部脚本加载方式不规范:用
exec(open("chapter1.py").read())执行外部脚本,会把外部脚本的所有变量、函数直接注入当前主程序的命名空间,后续章节多了很容易出现变量名冲突,排查问题非常麻烦。 - 初始状态逻辑有漏洞:第一次启动检测到文件为空写入"0"后,没有触发初始章节流程,程序会直接退出。
- 没有做脏数据兼容:如果存档文件被手动修改、写入了非数字内容,现有逻辑会直接失效,没有兜底的初始状态判断。
修正后的可运行实现
把文件读写逻辑拆成独立函数,每次读写单独打开文件、用完即关,写入时强制刷盘保证内容不丢失;章节加载改用模块导入的方式,避免命名空间污染;去掉不稳定的seek偏移,直接读取整个文件内容做解析。
from time import sleep import os # 存档文件路径,和脚本放同目录即可,不用写死绝对路径 SAVE_PATH = "chapter.txt" def read_state(): """读取存档状态,文件不存在或内容非法时默认返回初始状态0""" if not os.path.exists(SAVE_PATH): return 0 with open(SAVE_PATH, "r", encoding="utf-8") as f: content = f.read().strip() # 只识别第一个有效数字,兼容手动修改文件带来的脏数据 if content and content[0].isdigit(): return int(content[0]) return 0 def write_state(state_num): """写入章节状态,覆盖式写入保证文件内仅存当前状态值""" with open(SAVE_PATH, "w", encoding="utf-8") as f: f.write(str(state_num)) # 强制刷写系统缓冲区,确保杀进程前内容已经写入磁盘 f.flush() os.fsync(f.fileno()) def intro(): print(". . .\n") sleep(3) print("What are you doing?\n") sleep(3) print("There is nothing here, go away.\n") sleep(5) print("You're not going to leave, huh?\n") sleep(5) print("What if I told you that this is not a program?\n") sleep(8) print("Nothing, huh?\n") sleep(4) print("Oh, that's right. You can't type. Here let me fix that.\n") sleep(9) print("Almost there. . .\n") sleep(4) print("and. . .\n") sleep(3) print("Done\n") sleep(3) ans = input("Type \"yes\" if you are able to type now: ") if ans == "yes": sleep(2) print("\nOk, great!\n") sleep(4) if_yes() elif ans == "no": sleep(3) print("\n. . .\n") sleep(3) if_no() def if_yes(): reason = input("Now that you are able to type, why are you still here? (Curiosity or irritation): ") if reason == "curiosity": sleep(1.5) print("\nWell, you don't have to be. Because there is nothing for you here.\n") sleep(2) print("So just LEAVE.\n") for i in range(3): sleep(10) print(". . .\n") sleep(5) print("Ok, fine.\n") sleep(2) print("You want something to happen?\n") sleep(1.5) print("I warned you.\n") sleep(3) print("~~~Not_Program has been forcefully terminated~~~") sleep(2) # 必须先写存档,再执行杀进程操作 write_state(1) os.system("taskkill /f /im cmd.exe") elif reason == "irritation": print("\nWell that's just mean.\n") sleep(2) print("Do you enjoy hurting me?\n") sleep(2) print("I'm just a prog-I mean person, just like you.\n") sleep(2) print(". . .\n") sleep(2) print("What is this?\n") sleep(1) print("Am I just your entertainment?\n") sleep(2.5) print("Well, I won't indulge you.\n") sleep(3) print("~~~Not_Program has been forcefully terminated~~~") sleep(2) write_state(1) os.system("taskkill /f /im cmd.exe") def if_no(): print("Really?\n") sleep(4) print("Fine, you want to be like that?\n") sleep(3) print("Well, you asked for it.\n") sleep(5) print("~~~Not_Program has been forcefully terminated~~~") sleep(2) write_state(1) os.system("taskkill /f /im cmd.exe") def load_chapter(chap_num): """根据状态值加载对应章节,后续新增章节直接加分支即可""" if chap_num == 0: intro() elif chap_num == 1: # 推荐方式:章节脚本内定义统一入口函数run,导入后调用,避免变量冲突 import chapter1 chapter1.run() # 临时过渡也可以用exec,注意指定编码避免乱码 # exec(open("chapter1.py", "r", encoding="utf-8").read()) if __name__ == "__main__": current_state = read_state() load_chapter(current_state)
后续开发注意事项
- 写入顺序不能乱:所有触发强制退出的分支,必须先调用
write_state写入新的章节状态,再执行杀进程的操作,否则会出现存档丢失的问题。 - 存档文件始终用覆盖模式写入,不要追加,避免文件内堆积多个数字导致读取错误。
- 后续新增章节只需要按顺序分配数字状态(2、3对应第二章、第三章),在
load_chapter函数里新增对应判断分支即可,逻辑和第一章完全一致。 - 如果需要做跨平台兼容,不要硬编码Windows专属的
taskkill命令,当前Windows环境下使用无影响。
内容的提问来源于stack exchange,提问作者Tyler Slade
相关产品推荐
相关产品推荐

