问题描述
我在重命名模块后通过 numpy.load
加载对象时遇到问题.这是一个显示问题的简单示例.
I have a problem loading objects via numpy.load
after renaming a module.Here's a simple example showing the problem.
想象在 mymodule.py
中定义了一个类:
Imagine having a class defined in mymodule.py
:
class MyClass(object):
a = "ciao"
b = [1, 2, 3]
def __init__(self, value=2):
self.value = value
从 python 会话中,我可以简单地创建一个实例并保存它:
from a python session I can simply create an instance and save it:
import numpy as np
import mymodule
instance = mymodule.MyClass()
np.save("dump.npy", instance)
加载文件效果很好(即使是从同一文件夹中启动的新会话):
Loading the file works nicely (even from a fresh session started in the same folder):
np.load("dump.npy")
如果我现在重命名模块:
If I now rename the module:
mv mymodule.py mymodule2.py
加载失败.这是意料之中的,但我希望通过在加载之前导入模块:
the loading fails. This is expected, but I was hoping that by importing the module before loading:
import mymodule2 as mymodule
可以找到对象定义...但它不起作用.这意味着:1.我不明白它是如何工作的2. 我被迫在我正在部分重构的项目中保留指向重命名文件的符号链接.
the object definition could be found ... but it does not work.This means that: 1. I do not understand how it works 2. I am forced to keep a symbolic link to the renamed file in a project I am partially refactoring.
我还能做些什么来避免符号链接解决方案?并避免将来出现同样的问题?
Is there anything else I can do do avoid the symbolic link solution ? and to avoid having the same problem in the future ?
非常感谢,马可[这是我在这里的第一个问题,对不起,如果我做错了什么]
Thanks a lot,marco[this is my first question here, sorry If I am doing something wrong]
推荐答案
NumPy 使用 pickle
来处理带有对象的数组,但是在它上面添加了一个标题.因此,您需要做的不仅仅是编写自定义的Unpickler
:
NumPy uses pickle
for arrays with objects, but adds a header on top of it. Therefore, you'll need to do a bit more than coding a custom Unpickler
:
import pickle
from numpy.lib.format import read_magic, _check_version, _read_array_header
class RenamingUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == 'mymodule':
module = 'mymodule2'
return super().find_class(module, name)
with open('dump.npy', 'rb') as fp:
version = read_magic(fp)
_check_version(version)
dtype = _read_array_header(fp, version)[2]
assert dtype.hasobject
print(RenamingUnpickler(fp).load())
这篇关于重命名模块后取消对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!