2017-05-24 6 views
0

J'essaie de sérialiser un grand nombre de classes personnalisées sur disque en utilisant le pickle de python. Cependant, les classes ne sont pas sérialisées correctement. Après avoir regardé le docs, je comprends que ce que j'essaie de faire devrait fonctionner, mais ce n'est peut-être pas simplement parce que je ne comprends pas quelque chose.Pourquoi Pickle ne sérialise pas mon tableau de classes?

Mes classes sont définies au niveau supérieur du module. Et aucune exception PicklingError n'est déclenchée lors de la tentative de décapage.

Voici mon exemple de code. Décommenter Save() pour sérialiser; décommenter Load() pour charger. Lors du chargement, le tableau Synonymes de Term n'est pas rempli, mais l'objet principal de Term est désérialisé. Vous pouvez le voir en inspectant l'objet "loadedTerms" renvoyé par la fonction Load().

Qu'est-ce que je fais mal? Merci.

import pickle 

class Entry: 
    Text = "" 

    def __init__(self, text): 
     self.Text = text 

class Term: 

    Main = None 
    Synonyms = [] 


def Save(): 
    term = Term() 
    term.Main = Entry("Dog") 
    term.Synonyms.append(Entry("Canine")) 
    term.Synonyms.append(Entry("Pursue")) 
    term.Synonyms.append(Entry("Follow")) 
    term.Synonyms.append(Entry("Plague")) 

    terms = [] 
    terms.append(term) 

    with open('output.pickle', 'wb') as p: 
     pickle.dump(terms, p) 

def Load(): 
    loadedTerms = [] 

    with open('output.pickle', 'rb') as p: 
     loadedTerms = pickle.load(p) 

    return loadedTerms 


#Save() 
#terms = Load() 
+0

Les classes sont décapées par nom. Décapage d'une classe ne sauvera pas son état, et le décompacter ne tentera pas de générer une nouvelle copie de la classe ou de restaurer l'état de la classe au moment du décapage. – user2357112

+0

Assurez-vous que vos définitions de classe ne font pas ce que vous pensez qu'elles font. Mais autant que je sache, votre attribut 'Synonymes' * est * peuplé –

+0

Je suis toujours confus. Je m'excuse d'être dense. A quoi bon décaper un objet, alors? Et pourquoi décapage-t-il l'objet "Main" (je peux le désérialiser très bien), mais pas les éléments du tableau "Synonymes". Les docs disent: «Notez que le code ou les données de la classe ne sont pas décapés. Dans l'exemple suivant, l'attribut class attr n'est pas restauré dans l'environnement unpickling:« Mais alors il se retourne et dit: «De même, Lorsque les instances de classe sont décapées, le code et les données de leur classe ne sont pas décachetés avec elles, seules les données d'instance sont décapées. " –

Répondre

2

Pickle l'instance enregistre uniquement les attributs d'une classe, mais Synonyms est une liste, définie au niveau de la classe. Vous devez créer la liste dans un __init__ -method:

import pickle 

class Entry: 
    def __init__(self, text): 
     self.Text = text 

class Term: 
    def __init__(self): 
     self.Main = None 
     self.Synonyms = [] 

def Save(): 
    term = Term() 
    term.Main = Entry("Dog") 
    term.Synonyms.append(Entry("Canine")) 
    term.Synonyms.append(Entry("Pursue")) 
    term.Synonyms.append(Entry("Follow")) 
    term.Synonyms.append(Entry("Plague")) 

    terms = [] 
    terms.append(term) 

    with open('output.pickle', 'wb') as p: 
     pickle.dump(terms, p) 

def Load(): 
    with open('output.pickle', 'rb') as p: 
     loadedTerms = pickle.load(p) 
    return loadedTerms 
+0

Merci beaucoup pour votre réponse, cela a du sens.Une dernière question: vous dites que "Synonymes" est une liste, définie au niveau de la classe. Mais Main n'est-elle pas aussi définie au niveau de la classe dans mon exemple? –

+0

Vous redéfinissez 'Main' dans la deuxième ligne de' Save' en tant qu'attribut d'instance. – Daniel

+0

Aha! Donc j'utilise * des synonymes - ce qui est déclaré au niveau de la classe - parce que je me réfère à cela explicitement à travers l'appel .append() ... mais je REDEFINE Main en le définissant comme égal à quelque chose. OK. Comme vous pouvez le voir, je suis très vert avec python. Mon expérience est dans le monde de la langue C. Je vous remercie d'avoir pris le temps de répondre à mes questions de manière si informative. –