Python:使用两个模块时shelve的属性错误

1 投票
2 回答
782 浏览
提问于 2025-04-17 03:59

我正在尝试使用shelve模块,但遇到了一些问题。我想让一个模块调用另一个模块中的一个函数,这个函数会修改shelve里的一个文件。我做了一个原型(如下),它只是试图将一个变量设置为存储在shelve中的某个东西,并打印这个对象。

当我尝试这样做时,我遇到了以下属性错误:

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

我猜是因为它没有意识到我的'User'类存在,但我不太确定原因是什么。File1在它的主函数中调用了与File2相同的函数,并且在那种情况下正常工作。我很感激任何对此问题的帮助,我对这个问题感到困惑。

import SE_ex2

SE_ex2.cacheTest()

import shelve

cache_users = shelve.open("usersTest.cache")

class User(object):
    def __init__(self, name, num):
        self.name = name
        self.num = num

    def __str__(self):
        return "Name:{0}, Num={1}".format(self.name, self.num)

def cacheTest():
    obj = cache_users[ "user_red" ]
    print obj

if __name__ == "__main__":
    cacheTest()

#Used for creating the cache for the first time
#    red = User("red", 11)
#    green = User("green", 22)
#    blue = User("blue", 33)
#
#    cache_users['user_red'] = red
#    cache_users['user_green'] = green
#    cache_users['user_blue'] = blue
#    print "DONE"

完整的错误追踪信息:

Traceback (most recent call last):
  File "C:\Users\akaGrim\My Documents\Aptana Studio 3 Workspace\ShelveTest\SE_ex1.py", line 3, in <module>
    SE_ex2.cacheTest()
  File "C:\Users\akaGrim\My Documents\Aptana Studio 3 Workspace\ShelveTest\SE_ex2.py", line 14, in cacheTest
    obj = cache_users[ "user_red" ]
  File "C:\Python27\lib\shelve.py", line 122, in __getitem__
    value = Unpickler(f).load()
AttributeError: 'module' object has no attribute 'User'

2 个回答

0

我之前也遇到过类似的问题,和 pickle 有关。你可以试着把 User 类放在另一个文件里,这样在这两个文件中你就可以从同一个模块导入它。我觉得它在存储的时候是以 User 的名字存的,但当你取出来的时候,你希望它能明白 SE_ex2.User 是之前叫做 User 的那个东西。你也可以直接导入 User 类,像这样:

from SE_ex2 import User
import SE_ex2
SE_ex2.cache_test()
2

修复方法:

import SE_ex2
from SE_ex2 import User

SE_ex2.cacheTest()

被序列化的类需要在命名空间中

原因是 shelf 使用了 pickle,所以它使用了 User 类:

当你在使用自己的类时,必须确保这个类在读取 pickle 的进程的命名空间中可见。只有实例的数据会被序列化,而不是类的定义。类名用于找到构造函数,以便在反序列化时创建新的对象。来看这个例子,它将类的实例写入文件:

引用链接: http://www.doughellmann.com/PyMOTW/pickle/index.html#problems-reconstructing-objects

撰写回答