Comment supprimer les citations d'un initialiseur de classe lors de la lecture d'un fichier. Python

StackOverflow https://stackoverflow.com/questions/19825504

Question

Je stockage l'appel à une tâche de classe dans un tableau dans un fichier .dat. Je voudrais lire ce fichier et reconstruire les appels de classe.

Voici la classe que j'utilise en ce moment:

class Task:

    def __init__(self, name, timespent):
        self.name = name
        self.timespent = timespent

    def __repr__(self):
        return repr('Task("%s",%s)'%(self.name, self.timespent))

Voici la lecture du fichier:

task_list = []
with open("task_list2.dat", "r") as file:
    task_list = eval(file.readline())

Voici l'écriture dans le fichier:

with open("task_list2.dat", "w") as outFile:
    print(repr(task_list), file = outFile)

Et voici le contenu du fichier:['Task("class",20)']Où "classe" est le nom de la tâche.

Je comprends que le problème a à voir avec les citations simples autour de 'Task ("Class", 20)', mais je n'ai aucune idée de la façon de s'en débarrasser. Le message d'erreur que j'obtiens dit quelque chose dans le sens de: "STR Object n'a pas d'attribut 'nom'"

Comment puis-je supprimer ces citations afin que je puisse reconstruire les classes la prochaine fois que je lis le fichier?

Était-ce utile?

La solution

Vous ne voulez vraiment pas, vraiment, vraiment essayer d'utiliser repr et eval comme format de sérialisation.

Si vous venez d'utiliser, disons, pickle, vous n'auriez pas du tout ce problème:

with open("task_list2.dat", "wb") as outFile:
    pickle.dump(task_list, outFile)

with open("task_list2.dat", "rb") as file:
    task_list = pickle.load(file)

Beaucoup plus simple, oui?


Mais si vous voulez savoir comment résoudre le problème immédiat au lieu de le rendre hors de propos: vous avez plusieurs problèmes dans votre __repr__ Méthode, qui doivent toutes être corrigées si vous voulez qu'elle soit randonnée.

  • Vous gérez une représentation de chaîne… puis appelez repr dessus. Vous souhaitez renvoyer la représentation de la chaîne, pas une représentation de chaîne de la représentation de chaîne. Laissez simplement le repr.
  • Vous devez toujours déléguer au repr de sous-objets, pas le str. Si vous utilisez %-Format, cela signifie utiliser %r plutôt que %s.
  • N'essayez pas d'ajouter des citations autour des choses. Cela peut arriver à fonctionner si l'objet lui-même n'a pas de citations, de barreaux de barreaux, de caractères invisibles, etc., mais pourquoi compter sur cela? Si vous pensez que vous avez besoin de citations, c'est à peu près toujours un signe que vous avez enfreint la règle précédente, et vous devriez résoudre ce problème à la place.

Voici comment vous pouvez rédiger un REP-Trippable pour cette classe:

def __repr__(self):
    return 'Task(%r, %r)' % (self.name, self.timespent))

Et vous pouvez vérifier qu'il fait ce que vous voulez:

>>> t = Task('task name', 23.4)
>>> t
Task('task name', 23.4)
>>> eval(repr(t))
Task('task name', 23.4)

Bien sûr, dans votre exemple particulier, il suffit de résoudre le premier problème (en supprimant l'appel parasite à repr) se serait débarrassé des citations uniques et a fait cet exemple particulier. Vous pouvez également pirater ce côté lecture en appelant eval deux fois. Ou, pour cet exemple particulier, même en appelant eval(s[1:-1]) ou eval(s.strip("'")). Mais tout "correctif" comme ça va simplement rendre plus difficile de déboguer les problèmes généraux que vous allez rencontrer une fois que vous aurez, par exemple, un nom qui n'est pas aussi simple qu'un seul mot tout-asci-letter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top