Domanda

Sto memorizzando la chiamata a un'attività di classe in un array in un file .dat. Vorrei leggere questo file e ricostruire le chiamate di classe.

Ecco la classe che sto usando in questo momento:

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))

Ecco la lettura dal file:

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

Ecco la scrittura del file:

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

Ed ecco il contenuto del file:['Task("class",20)']Dove "classe" è il nome dell'attività.

Capisco che il problema ha a che fare con le singole citazioni "Task (" Class ", 20)", ma non ho idea di come sbarazzarsene. Il messaggio di errore che ricevo dice qualcosa sulla riga di: "L'oggetto ST non ha un 'nome'"

Come posso rimuovere quelle citazioni in modo da poter ricostruire le classi la prossima volta che ho letto il file?

È stato utile?

Soluzione

Davvero, davvero, davvero, non vuoi provare a usare repr e eval come formato di serializzazione.

Se hai appena usato, dire, pickle, non avresti affatto questo problema:

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)

Molto più semplice, sì?


Ma se vuoi sapere come risolvere il problema immediato invece di renderlo irrilevante: hai più problemi nel tuo __repr__ Metodo, tutto ciò che deve essere risolto se si desidera che sia a rotazione.

  • Genera una rappresentazione di stringa ... e poi chiama repr su di esso. Vuoi restituire la rappresentazione della stringa, non una rappresentazione di stringa di la rappresentazione della stringa. Lascia fuori il repr.
  • Dovresti sempre delegare al repr di sotto-oggetti, non il str. Se stai usando %-Formattazione, ciò significa usare %r piuttosto che %s.
  • Non provare ad aggiungere citazioni intorno alle cose. Ciò può funzionare se l'oggetto stesso non ha citazioni, retroscena, personaggi invisibili, ecc. In esso, ma perché fare affidamento su questo? Se pensi di aver bisogno di citazioni, è praticamente sempre un segno che hai infranto la regola precedente e dovresti risolverlo invece.

Ecco come puoi scrivere un RAPR di andata e ritorno per questa classe:

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

E puoi verificare che faccia quello che vuoi:

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

Naturalmente nel tuo esempio particolare, basta risolvere il primo problema (rimuovendo la chiamata spuria a repr) si sarebbe sbarazzato delle citazioni singole e fatto funzionare quel particolare esempio. Potresti anche hackerarlo dalla lettura chiamando eval due volte. O, per questo particolare esempio, anche chiamando eval(s[1:-1]) o eval(s.strip("'")). Ma qualsiasi "correzione" del genere rende più difficile il debug dei problemi generali in cui ti imbatterai una volta che hai, ad esempio, un nome che non è semplice come una singola parola All-ASCII-Letter.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top