如何在Python中更改文本文件中存储的数据?

时间:2016-01-19 22:25:34

标签: python csv python-3.x

我正在尝试创建一个基本的数学测验,并且需要能够将用户的名字存储在他们的分数旁边。为了确保我可以动态编辑数据而不管用户名称的长度或分数中的位数,我决定用逗号分隔名称和分数并使用分割功能。我是python中文件处理的新手,所以不知道我是否使用了错误的模式(" r +")但是当我完成测验时,我的分数没有记录在全部,没有任何内容添加到文件中。这是我的代码:

for line in class_results.read():
if student_full_name in line:
    student = line.split(",")
    student[1] = correct
    line.replace(line, "{},{}".format(student_full_name, student[1]))
else:
    class_results.write("{},{}".format(student_full_name, correct))

请让我知道如何让这个系统运作起来。提前谢谢。

2 个答案:

答案 0 :(得分:0)

r+打开文件进行阅读和写作,并总结:

仅在读取文件时

r

w仅用于写入(将擦除具有相同名称的现有文件)

a打开要追加的文件;写入文件的任何数据都会自动添加到最后。

我建议使用 json yaml 语法,而不是使用逗号分隔来获得好处,在这种情况下,它更适合。

  1. scores.json
  2. {
          "student1": 12,
          "student2": 798
    }
    

    解决方案:

    import json
    
    with open(filename, "r+") as data:
        scores_dict = json.loads(data.read())
        scores_dict[student_full_name] = correct # if already exist it will be updated otherwise it will be added
        data.seek(0)
        data.write(json.dumps(scores_dict))
        data.truncate()
    
    1. scores.yml 将如下所示:
    2. student1: 45
      student2: 7986
      

      解决方案:

      import yaml
      
      with open(filename, "r+") as data:
          scores_dict = yaml.loads(data.read())
          scores_dict[student_full_name] = correct # if already exist it will be updated otherwise it will be added
          data.seek(0)
          data.write(yaml.dump(scores_dict, default_flow_style=False))
          data.truncate()
      

      安装yaml python包:pip install pyyaml

答案 1 :(得分:0)

修改文件通常是一种不好的方法。它可能会导致错误,从而导致生成的文件为半个新数据,一半旧,分裂点已损坏。通常的模式是写入一个新文件,然后用新文件原子地替换旧文件,因此要么拥有整个原始旧文件和部分新文件,要么使用新文件,而不是两者的混合文件。

鉴于您的示例代码,以下是如何修复它:

import csv
import os
from tempfile import NamedTemporaryFile

origfile = '...'
origdir = os.path.dirname(origfile)

# Open original file for read, and tempfile in same directory for write
with open(origfile, newline='') as inf, NamedTemporaryFile('w', dir=origdir, newline='') as outf:
    old_results = csv.reader(inf)
    new_results = csv.writer(outf)
    for name, oldscore in old_results:
        if name == student_full_name:
            # Found our student, replace their score
            new_results.writerow((name, correct))
            # The write out the rest of the lines unchanged
            new_results.writerows(old_results)
            # and we're done
            break
        else:
            new_results.writerow((name, oldscore))
    else:
        # else block on for loop executes if loop ran without break-ing
        new_results.writerow((student_full_name, correct))

    # If we got here, no exceptions, so let's keep the new data to replace the old
    outf.delete = False

# Atomically replaces the original file with the temp file with updated data
os.replace(outf.name, origfile)