【问题标题】:How do I pickle a dictionary containing a module & class?如何腌制包含模块和类的字典?
【发布时间】:2016-10-20 14:50:04
【问题描述】:

我需要将模块和类分配给字典键。然后将该字典腌制到文件中。稍后,加载 pkl 文件,然后根据该字典键值导入并实例化该类。

我试过了:

import module_example
from module_example import ClassExample

dictionary = {'module': module_example, 'class': ClassExample)

但它不会在 pkl 文件中存储对 module_exmaple.py 的引用。

我尝试了使用字符串而不是模块和类名的解决方法。但是,如果模块名称被重构或位置发生变化,这将导致一团糟。

有没有直接这样做?以某种方式将模块和类的引用存储在字典中,然后根据该引用导入和实例化?

【问题讨论】:

    标签: python python-3.x pickle


    【解决方案1】:

    这适用于单个班级。如果你想在多个模块和类中这样做,你可以扩展下面的代码。

    module_class_writer.py

    import module_example
    from module_example import ClassExample
    
    included_module = ["module_example"]
    d = {}
    for name, val in globals().items():
        if name in included_module:
            if "__module__" in dir(val):
                d["module"] = val.__module__
                d["class"] = name
    
    #d = {'module': module_example, 'class': ClassExample}
    
    import pickle
    filehandler = open("imports.pkl","wb")
    pickle.dump(d, filehandler)
    filehandler.close()
    

    module_class_reader.py

    import pickle
    filehandler = open("imports.pkl",'rb')
    d = pickle.load(filehandler)
    filehandler.close()
    
    def reload_class(module_name, class_name):
        mod = __import__(module_name, fromlist=[class_name])
        reload(mod)
        return getattr(mod, class_name)
    
    if "class" in d and "module" in d: 
        reload(__import__(d["module"]))
        ClassExample = reload_class(d["module"], d["class"])
    

    【讨论】:

      【解决方案2】:

      如果您希望未腌制的类与腌制的对象完全相同,则必须存储该类的代码(例如,使用像 dill 这样的外部库)。

      否则,标准 pickle 无法存储对将“幸存”重构的类的引用。

      【讨论】:

      • 我不需要同一个对象。但我需要一个类的参考。这样我就可以基于该引用实例化一个新对象。如果该类名和或位置被重构,我希望引用也能反映这一点。有什么办法可以做到吗?
      • @Emily:在这样的重构之后,Python 无法判断新类和旧类是“同一个类”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      相关资源
      最近更新 更多