写入文件python - Linebreak issue(\ n)

时间:2014-12-25 15:48:39

标签: python windows

我遇到一个问题,即函数只会覆盖.txt文件中已存在的行。当游戏退出时,该函数应该为文件写一个高分(我通过跟随youtube教程制作了一个蛇游戏)。我无法弄清楚为什么它不会开始新的生产线,任何人都可以解释它背后的逻辑,以及我如何解决它?我读到的地方不是" w"在f.open()中,我应该键入" rb"或者其他的东西。因为我对这个"写到文件"有点新意。好事,我觉得很难。

另外,我想在文件中将高分从最高到最低排序(换句话说,将finalScore从最高到最低排序)。我不知道我应该如何继续编码,所以我会提供一些帮助。你看,我想把当前的高分打印到控制台(为了得分)

下面是代码:

import random
import time

name = "Andreas"
finalScore = random.randint(1,10)

def scoreToFile(finalScore):
    #Has to be generated here, since we need the exact current time
    currentTime = time.strftime("%c")
    print("Sucsessfully logged score (finalScore) to highscores.txt")
    f = open("highscores.txt", "w")
    #fileOutput = [(currentTime, ":", name, "-", finalScore)]
    fileOutput = [(finalScore, "-", name, currentTime)]
    for t in fileOutput:
        line = ' '.join(str(x) for x in t)
        f.write(line + "\n")
    f.close()

scoreToFile(finalScore)

无论如何,圣诞快乐我的同伴蟒蛇极客们! :d

3 个答案:

答案 0 :(得分:3)

1)一个选项是以追加模式打开文件。 替换:

f = open("highscores.txt", "w")

使用:

f = open("highscores.txt", "a")

2)另一个选择是替换这个块,

f = open("highscores.txt", "w")
#fileOutput = [(currentTime, ":", name, "-", finalScore)]
fileOutput = [(finalScore, "-", name, currentTime)]
for t in fileOutput:
    line = ' '.join(str(x) for x in t)
    myfile.write(line + "\n")
f.close()

并使用带风格的

with open("highscores.txt", "a") as myfile:
    #fileOutput = [(currentTime, ":", name, "-", finalScore)]
    fileOutput = [(finalScore, "-", name, currentTime)]
    for t in fileOutput:
        line = ' '.join(str(x) for x in t)
        myfile.write(line + "\n")

我更喜欢第二种风格,因为它更安全,更干净。

答案 1 :(得分:2)

模式w会覆盖现有文件;模式'a'追加。此外,处理文件的最佳方式通常是使用with语句,以确保代表您结束;这样:

fileOutput = [(finalScore, "-", name, currentTime)]
with open("highscores.txt", "a") as f:
    for t in fileOutput:
        line = ' '.join(str(x) for x in t)
        f.write(line + "\n")

对于排序,您需要能够从一行中提取最终得分作为数字:

def minus_score(line):
    return -int(line.split()[0])

然后总工作将完成:

def sorted_by_score():
    with open("highscores.txt", "r") as f:
        result = list(f)
    return sorted(result, key=minus_score)

这将为您提供按分数升序排序的列表行(后者是score否定数字的原因,尽管也可以选择让它返回数字并反转排序),你循环并进一步处理。

补充:所以关于OP的请求,这里是整个程序可能是怎样的(假设存在一个游戏并且返回玩家名称和最终得分的函数,或者当没有更多游戏时返回None要播放,节目必须退出)。

import time

def play_game():
    """ play a game and return name, finalscore;
        return None to mean no more games, program finished.
        THIS function you'd better code yourself!-)
    """

def scoreToFile(name, finalScore):
    """ Add a name and score to the high-scores file. """
    currentTime = time.strftime("%c")
    fileOutput = finalScore, "-", name, currentTime
    line = ' '.join(str(x) for x in fileOutput)
    with open("highscores.txt", "a") as f:
        f.write(line + "\n")

def minus_score(line):
    """ just for sorting purposes, not called directly. """
    return -int(line.split()[0])

def sorted_by_score():
    """ return list of score lines sorted in descending order of score. """
    with open("highscores.txt", "r") as f:
        return sorted(f, key=minus_score)

def main():
    while True:
        game_result = play_game()
        if game_result is None: break
        scoreToFile(*game_result)
    for line in sorted_by_score:
        print(line.strip())

答案 2 :(得分:1)

正如其他人所提到的那样,问题是你没有在附加模式下打开文件,所以它每次都会覆盖它而不是添加它。

但是,如果您还想将文件中的数据保持排序,则每次都要覆盖它,因为其内容的顺序可能会随着添加而改变。要做到这一点,首先需要读取内容,更新数据,然后将其写回。

这是您的功能的修改版本。我还更改了文件中的数据如何存储到所谓的Comma (or Character) Separated Values (CSV)格式,因为Python包含一个csv模块,这使得它可以非常容易地读取,写入以及使用这些文件执行其他操作。

import csv
import random
import time

highscores_filename = "highscores.txt"
HighScoresFirst = True  # Determines sort order of data in file

def scoreToFile(name, finalScore):
    currentTime = time.strftime("%c")
    # Try reading scores from existing file.
    try:
        with open(highscores_filename, "r", newline='') as csvfile:
            highscores = [row for row in csv.reader(csvfile, delimiter='-')]
    except FileNotFoundError:
        highscores = []
    # Add this score to the end of the list.
    highscores.append([str(finalScore), name, currentTime])
    # Sort updated list by numeric score.
    highscores.sort(key=lambda item: int(item[0]), reverse=HighScoresFirst)
    # Create/rewrite highscores file from highscores list.
    with open(highscores_filename, "w", newline='') as csvfile:
        writer = csv.writer(csvfile, delimiter='-')
        writer.writerows(highscores)
    print("successfully logged score (finalScore) to highscores.txt")

# Simulate using the function several times.
name = "Name"
for i in range(1, 4):
    finalScore = random.randint(1,10)
    scoreToFile(name + str(i), finalScore)
    time.sleep(random.randint(1,3))  # Pause so time values will vary.