Pergunta

Estou armazenando a chamada para uma tarefa de classe em uma matriz em um arquivo .dat. Eu gostaria de ler este arquivo e reconstruir as chamadas da classe.

Aqui está a aula que estou usando agora:

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

Aqui está a leitura do arquivo:

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

Aqui está a escrita para o arquivo:

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

E aqui está o conteúdo do arquivo:['Task("class",20)']Onde "classe" é o nome da tarefa.

Entendo que o problema tem a ver com as citações únicas em torno de 'tarefa ("classe", 20)', mas não tenho idéia de como me livrar delas. A mensagem de erro que recebo diz algo parecido com: "O objeto str não tem atributo 'nome'"

Como posso remover essas cotações para poder reconstruir as aulas na próxima vez que leio o arquivo?

Foi útil?

Solução

Você realmente, realmente, realmente não quer tentar usar repr e eval como formato de serialização.

Se você acabou de usar, digamos, pickle, você não teria esse 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)

Muito mais simples, sim?


Mas se você quiser saber como resolver o problema imediato em vez de torná -lo irrelevante: você tem vários problemas em seu __repr__ Método, todos os quais precisam ser corrigidos se você quiser que ele seja redondo.

  • Você gera uma representação de string… e depois ligue repr nele. Você quer devolver a representação da string, não uma representação de string do a representação da string. Apenas deixe de fora o repr.
  • Você deve sempre delegar ao repr de subobjetos, não o str. Se você está usando %-Formatting, isso significa usar %r ao invés de %s.
  • Não tente adicionar cotações sobre as coisas. Isso pode funcionar se o objeto em si não tem cotações, barras de barriga, personagens invisíveis etc., mas por que confiar nisso? Se você acha que precisa de cotações, é sempre um sinal de que você quebrou a regra anterior e você deve consertar isso.

Veja como você pode escrever uma REP redonda para esta aula:

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

E você pode verificar se faz o que deseja:

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

É claro que em seu exemplo específico, apenas corrigindo o primeiro problema (removendo a chamada espúria para repr) teria se livrado das citações únicas e feito esse exemplo em particular funcionar. Você também pode invadir isso do lado da leitura ligando eval duas vezes. Ou, para este exemplo em particular, mesmo ligando eval(s[1:-1]) ou eval(s.strip("'")). Mas qualquer "correção" como isso apenas dificultará a depuração dos problemas gerais que você encontrará quando tiver, por exemplo, um nome que não seja tão simples quanto uma única palavra-letra All-ASCII.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top