2010-04-08 7 views
2

J'essaie de mettre certains sites que j'ai rampés dans une étagère, mais le shelve n'acceptera aucun objet Site. Il acceptera les listes, les chaînes, les tuples, ce que vous avez, mais dès que je mets un objet Site, il se bloque quand j'essaye d'obtenir le contenu de l'étagèreshelve donne une erreur étrange

Alors quand je remplis mon étagère comme ceci :

def add_to_shelve(self, site): 
    db = shelve.open("database") 
    print site, site.url 
    for word in site.content: 
     db[word] = site.url #site.url is a string, word has to be one too 

shelve.open("database")['whatever'] fonctionne parfaitement.

Mais si je fais ceci:

def add_to_shelve(self, site): 
    db = shelve.open("database") 
    print site, site.url 
    for word in site.content: 
     db[word] = site #site is now an object of Site 

shelve.open("database")['whatever'] erreurs avec ce message d'erreur:

AttributeError: 'module' object has no attribute 'Site' 

Je suis complètement déconcerté, et les pythondocs, étrangement, ne pas beaucoup d'info non plus. Tout ce qu'ils disent est que la clé dans un shelve doit être une chaîne, mais la valeur ou les données peuvent être "un objet arbitraire"

Répondre

5

Il semble que vous ayez refaçonné votre code après avoir enregistré des objets dans le rayonnage. Lors de la récupération des objets de l'étagère, Python reconstruit l'objet et doit trouver la classe d'origine que vous avez probablement déplacée. Ce problème est typique lorsque vous travaillez avec pickle (comme le fait le module shelve). La solution, comme le suggère pduel, est de fournir une référence de compatibilité ascendante vers la classe dans le même emplacement qu'auparavant, de sorte que pickle puisse le trouver. Si vous réenregistrez tous les objets, en reconstruisant ainsi les cornichons, vous pouvez supprimer cette référence à la rétrocompatibilité.

0

Il semble que Python recherche un constructeur pour un objet 'Site', et non le trouver. Je n'ai pas utilisé shelve, mais je me souviens que les règles pour ce qui peut être mariné sont byzantines, et je soupçonne que les règles du shelve sont similaires.

Essayez d'ajouter la ligne:

site = sitemodule.Site

(avec le nom du module fournissant 'Site') avant d'essayer unshelving. Cela garantit qu'une classe Site peut être trouvée.