重命名模块后取消对象

重命名模块后取消对象

本文介绍了重命名模块后取消对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在重命名模块后通过 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())

这篇关于重命名模块后取消对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 05:26