Pregunta

Estoy almacenando la llamada a una tarea de clase en una matriz en un archivo .dat. Me gustaría leer este archivo y reconstruir las llamadas de clase.

Aquí está la clase que estoy usando ahora mismo:

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

Aquí está la lectura del archivo:

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

Aquí está la escritura en el archivo:

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

Y aquí está el contenido del archivo:['Task("class",20)']Donde "clase" es el nombre de la tarea.

Entiendo que el problema tiene que ver con las citas individuales sobre 'tarea ("clase", 20)', pero no tengo idea de cómo deshacerme de ellas. El mensaje de error que recibo dice algo en la línea de: "El objeto STR no tiene 'nombre' de atributo"

¿Cómo puedo eliminar esas citas para que pueda reconstruir las clases la próxima vez que lea el archivo?

¿Fue útil?

Solución

Realmente, realmente, realmente no quieres intentar usar repr y eval como formato de serialización.

Si acabas de usar, digamos, pickle, no tendrías este problema en absoluto:

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)

Mucho más simple, ¿sí?


Pero si desea saber cómo resolver el problema inmediato en lugar de hacerlo irrelevante: tiene múltiples problemas en su __repr__ Método, todo el cual debe solucionarse si desea que sea de tripal redonda.

  • Generas una representación de cadena ... y luego llamas repr en eso. Desea devolver la representación de la cadena, no una representación de cadena de la representación de la cadena. Solo deja fuera el repr.
  • Siempre debes delegar al repr de subobjetos, no el str. Si estás usando %-Formatting, eso significa usar %r más bien que %s.
  • No intentes agregar citas sobre cosas. Eso puede pasar que funcione si el objeto en sí no tiene citas, barras de chaqueta, caracteres invisibles, etc. en él, pero ¿por qué confiar en eso? Si cree que necesita citas, siempre es una señal de que rompió la regla anterior, y debe arreglarlo.

Así es como puedes escribir un REP de redondeo para esta clase:

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

Y puedes verificar que haga lo que quieres:

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

Por supuesto, en su ejemplo particular, simplemente solucionando el primer problema (eliminando la llamada espuria a repr) se habría librado de las citas individuales e hizo que ese ejemplo particular funcionara. También podrías piratear eso en el lado de la lectura llamando eval dos veces. O, para este ejemplo en particular, incluso llamando eval(s[1:-1]) o eval(s.strip("'")). Pero cualquier "arreglo" como ese solo hará que sea más difícil depurar los problemas generales con los que te encontrarás una vez que tengas, por ejemplo, un nombre que no es tan simple como una sola palabra de Letter All-Ahib.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top