You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:24:20