I usually store the player names and high-scores as a list of lists (e.g. [['Joe', 50], ['Sarah', 230], ['Carl', 120]]), because you can sort and slice them (for example if there should be a maximum of 10 entries). You can save and load the list with the json module (json.dump and json.load) or with pickle.
import json
from operator import itemgetter
import pygame as pg
from pygame import freetype
pg.init()
BG_COLOR = pg.Color('gray12')
BLUE = pg.Color('dodgerblue')
FONT = freetype.Font(None, 24)
def save(highscores):
    with open('highscores.json', 'w') as file:
        json.dump(highscores, file)  # Write the list to the json file.
def load():
    try:
        with open('highscores.json', 'r') as file:
            highscores = json.load(file)  # Read the json file.
    except FileNotFoundError:
        return []  # Return an empty list if the file doesn't exist.
    # Sorted by the score.
    return sorted(highscores, key=itemgetter(1), reverse=True)
def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    highscores = load()  # Load the json file.
    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                return
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_s:
                    # Save the sorted the list when 's' is pressed.
                    # Append a new high-score (omitted in this example).
                    # highscores.append([name, score])
                    save(sorted(highscores, key=itemgetter(1), reverse=True))
        screen.fill((30, 30, 50))
        # Display the high-scores.
        for y, (hi_name, hi_score) in enumerate(highscores):
            FONT.render_to(screen, (100, y*30+40), f'{hi_name} {hi_score}', BLUE)
        pg.display.flip()
        clock.tick(60)
if __name__ == '__main__':
    main()
    pg.quit()
The highscores.json file would then look like this:
[["Sarah", 230], ["Carl", 120], ["Joe", 50]]