shelve出现奇怪错误

2 投票
2 回答
1141 浏览
提问于 2025-04-15 21:23

我正在尝试把一些我抓取的网站放进一个架子里,但这个架子不接受任何网站对象。它可以接受列表、字符串、元组等等,但一旦我放入一个网站对象,当我尝试获取架子里的内容时就会崩溃。

所以当我这样填充我的架子时:

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'] 完全没问题。

但如果我这样做:

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'] 就会出现错误,错误信息是:

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

我完全搞不懂,而且奇怪的是,Python的文档里也没有太多信息。他们只说架子的键必须是字符串,但值或数据可以是“任意对象”。

2 个回答

0

看起来Python在寻找一个'Site'对象的构造函数,但找不到。我没有用过shelve,但我记得关于可以被“腌制”的东西的规则非常复杂,而且我怀疑shelve的规则也差不多。

试着在你尝试解开shelve之前,加上这一行:

Site = sitemodule.Site

(这里的'sitemodule'是提供'Site'的模块名)。这样可以确保能找到Site类。

5

看起来你在把对象保存到shelve之后对代码进行了重构。当你从shelve中取出对象时,Python会重新构建这个对象,它需要找到原来的类,而你可能已经把这个类移动了。这种问题在使用pickle(就像模块所做的那样)时很常见。

解决办法,正如pduel所建议的,是在原来的位置提供一个向后兼容的类引用,这样pickle就能找到它。如果你重新保存所有对象,从而重新构建这些pickle文件,那么就可以去掉这个向后兼容的引用。

撰写回答