动态加载模块的pickle和unpickle

44u64gxh  于 2021-09-08  发布在  Java
关注(0)|答案(0)|浏览(211)

我用以下方式创建一个对象(我知道这很可怕,不要问为什么,这是必要的):

with tempfile.NamedTemporaryFile(suffix='.py') as temp:
    temp.write(code.encode('utf-8'))
    import importlib.util
    spec = importlib.util.spec_from_file_location('a_temp_module', temp.name)
    temp_module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(temp_module)
    special_snowflake_object = temp_module.SpecialSnowflake()

现在上课 SpecialSnowflake 实现两种保存和加载方法,基本上只是对其进行pickle和unpickle:

def save(self, file_path: str):
    with open(file_path, 'w') as fp:
        pickle.dump(self, fp)

@staticmethod
def load(file_path: str):
    with open(file_path, 'r') as fp:
        return pickle.load(fp)

但是,一打电话 save 我得到一个错误: _pickle.PicklingError: Can't pickle <class 'a_temp_module.SpecialSnowflake'>: import of module 'a_temp_module' failed 这是相当奇怪的,因为我不知道你可以携带从调用示例化的对象,而不携带类定义本身,但显然,这就是这里发生的事情。
我假设加载和保存可以通过以下方式完成:

with tempfile.NamedTemporaryFile(suffix='.py') as temp:
    temp.write(code.encode('utf-8'))
    import importlib.util
    spec = importlib.util.spec_from_file_location('a_temp_module', temp.name)
    temp_module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(temp_module)
    special_snowflake_object_1.save(path_to_pickle)
    special_snowflake_object_2 = temp_module.SpecialSnowflake.load(path_to_pickle)

但我更喜欢 save 要想在不需要重新加载模块的情况下调用,我想对于load来说没有其他选择。我目前的想法是,通过将模块的加载隐藏在 save 函数并将代码作为对象的属性进行携带。。。但我希望有一个更优雅的解决方案。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题