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

Python写入CSV格式异常:内容换行与多余引号问题排查

Python测验程序CSV写入问题排查与修复方案

问题情况

你开发的Python测验程序需要把用户添加的试题(question、answer、questiontype、subject)写入CSV同一行,比如期望输出:

when did WWII start,1939,multiple choice,History

但实际写入时内容被拆成多行,还出现多余引号,导致CSV格式混乱。

问题根源

  1. Text控件的换行符残留:tkinter的Text.get("1.0", "end")会把输入内容末尾的换行符(\n)也取出来,csv模块遇到字段里的换行符时,会自动用引号包裹该字段,同时换行符会让内容拆成多行。
  2. 重复添加"New Subject":openAdding函数里把UniqueSubject.append("New Subject")放在了循环内部,导致每次读取CSV行都会添加一次,下拉菜单里会出现多个重复的"New Subject"选项。
  3. 按钮拼写错误:else分支里的按钮文本写成了"Sumbit",应该是"Submit"。

修正方案

  1. 去除Text输入的末尾换行:把Question.get("1.0", "end")改成Question.get("1.0", "end-1c"),end-1c表示取到最后一个字符之前,自动去掉末尾的换行符;Answer控件同理。
  2. 调整"New Subject"添加位置:把UniqueSubject.append("New Subject")移到循环外面,确保下拉菜单里只出现一次"New Subject"。
  3. 修正按钮拼写错误:把"Sumbit"改成"Submit"。

完整修正代码

import csv
import tkinter as tk

root = tk.Tk()  # 假设root已在其他地方定义,此处补全必要初始化

def SaveToCsv(subject, question, answer, questiontype):
    with open(r"BankOfQuestions.csv", "a", newline='', encoding='utf-8') as Bank:
        writer = csv.writer(Bank, delimiter=',')
        writer.writerow([question, answer, questiontype, subject])

def AddNewQuestion(subject):
    window = tk.Toplevel(root)
    window.title(f"Add a new question for {subject}")

    if subject == "New Subject":
        Label1 = tk.Label(window, text="Enter name of subject")
        Label1.pack()
        SubjectTitle = tk.StringVar()
        NameOfSubject = tk.Entry(window, textvariable=SubjectTitle, font=("Ariel", 10))
        NameOfSubject.pack()

        Label2= tk.Label(window, text="Enter the question", pady=12)
        Label2.pack()
        Question = tk.Text(window, font=("Ariel", 10), height=9)
        Question.pack()

        Label3 = tk.Label(window, text= "Enter the answer", pady=12)
        Label3.pack()
        Answer= tk.Text(window, font=("Ariel", 10), height=9)
        Answer.pack()

        qtypes = ["multiple choice", "written"]
        QuestionType = tk.StringVar()
        QuestionType.set("Select question type")
        drop = tk.OptionMenu(window, QuestionType, *qtypes)
        drop.pack(pady=12)

        # 去除Text输入末尾的换行符
        Submit = tk.Button(window, text="Submit", command= lambda: SaveToCsv(SubjectTitle.get(), Question.get("1.0", "end-1c"), Answer.get("1.0", "end-1c"), QuestionType.get()))
        Submit.pack()
    else:
        Label2= tk.Label(window, text="Enter the question", pady=12)
        Label2.pack()
        Question = tk.Text(window, font=("Ariel", 10), height=9)
        Question.pack()

        Label3 = tk.Label(window, text= "Enter the answer", pady=12)
        Label3.pack()
        Answer= tk.Text(window,font=("Ariel", 10), height=9)
        Answer.pack()

        qtypes = ["multiple choice", "written"]
        QuestionType = tk.StringVar()
        QuestionType.set("Select question type")
        drop = tk.OptionMenu(window, QuestionType, *qtypes)
        drop.pack(pady=12)

        # 修正按钮拼写+去除换行符
        Submit = tk.Button(window, text="Submit", command= lambda :SaveToCsv(subject, Question.get("1.0","end-1c"), Answer.get("1.0","end-1c"), QuestionType.get()))
        Submit.pack()

def openAdding():
    window = tk.Toplevel(root)
    window.title("Add a question")
    UniqueSubject = []
    try:
        with open("BankOfQuestions.csv", "r") as Bank:
            Stuff = csv.reader(Bank)
            for line in Stuff:
                # 处理空行,避免索引越界
                if len(line) <4:
                    continue
                subject = line[3]
                if subject == "Subject" or subject == "" or subject in UniqueSubject:
                    pass
                else:
                    UniqueSubject.append(subject)
        # 把New Subject移到循环外,只添加一次
        UniqueSubject.append("New Subject")
    except FileNotFoundError:
        # 首次运行文件不存在时,直接添加New Subject
        UniqueSubject.append("New Subject")
    
    menu = tk.StringVar()
    menu.set("Pick a Subject")
    drop = tk.OptionMenu(window, menu, *UniqueSubject, command= lambda x: AddNewQuestion(menu.get()))
    drop.pack()
    
    Quitter = tk.Button(window, text="Quit", font=("Ariel", 20), command=window.destroy)
    Quitter.pack()

# root.mainloop()  # 按需启用主窗口循环

额外优化

新增了try-except处理CSV文件不存在的情况,避免首次运行报错;同时处理CSV内的空行,防止索引越界问题。

内容的提问来源于stack exchange,提问作者Herwin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:30:20