python - 如何加载旧的 pickle 文件?

标签 python python-2.7 module pickle

我有一个旧的 pickle 文件,当我尝试加载它时出现错误

ImportError: No module named oldname.submodule

这是因为oldname早已被重命名为newname

如何加载这个 pickle 文件?

我可以创建一个从 oldnamenewname 的符号链接(symbolic link),但我想知道是否有办法使模块 oldname.* 引用到 newname.* 而不触及文件系统?

最佳答案

sys.modules 中添加条目,而不是创建第二个并行模块和外部依赖项的符号链接(symbolic link)。为了测试,我 pickle 了一个类实例,然后重命名了模块

td@mintyfresh ~/tmp $ cat oldname.py
class Foo(object):
    def __init__(self):
        self.name = 'bar'

td@mintyfresh ~/tmp $ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import oldname
>>> foo = oldname.Foo()
>>> foo.name
'bar'
>>> import pickle
>>> pickle.dump(foo, open('test.pkl', 'wb'), 2)
>>> exit()
td@mintyfresh ~/tmp $ mv oldname.py newname.py
td@mintyfresh ~/tmp $ rm oldname.*

现在加载失败

td@mintyfresh ~/tmp $ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import newname
>>> import pickle
>>> foo = pickle.load(open('test.pkl', 'rb'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "/usr/lib/python2.7/pickle.py", line 1124, in find_class
    __import__(module)
ImportError: No module named oldname

但是如果我在 sys.modules 中复制模块,它就可以工作。有趣的是,类实例具有新的模块名称。

>>> import sys
>>> sys.modules['oldname'] = sys.modules['newname']
>>> foo = pickle.load(open('test.pkl', 'rb'))
>>> foo
<newname.Foo object at 0x7f6b837d3310>

注意买者:如果类本身发生了很大变化,pickle 无论如何都会失败。

关于python - 如何加载旧的 pickle 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41554738/

相关文章:

python - 如何在 Python 中获取线程 id?

python - Pandas df 操作 - 将数据分成 2 列

python - 在python中以编程方式查找列表中的最大元素

python-2.7 - 如何并排使用 Tkinter 和 Socket

c - Fortran 和 c 在源代码如何接口(interface)和编译在一起方面的细微差别

Python http 错误日志记录

python - 身份验证无法使用pymongo连接到mongodb

linux - 将模块.C添加到linux内核

python - 当类也在不同的模块中时从另一个模块访问对象?

python - 正则表达式中的返回组与字符串匹配