代码之家  ›  专栏  ›  技术社区  ›  Erik Giesen

Python pickle/dill:在模块中定义的类的实例(即不是顶层)可以以某种方式被挑选出来吗?

  •  0
  • Erik Giesen  · 技术社区  · 1 年前

    根据文件,这是不可能的。但我想知道是否有解决办法。

    这似乎是一个非常随意的限制,会打乱整个代码结构

    我试着暂时将我的班级提升到最高水平,结果正如预期的那样。

    我尝试了以下链接中的“解决方案3”,但似乎不起作用: https://copyprogramming.com/howto/i-can-pickle-local-objects-if-i-use-a-derived-class

    我有以下文件夹结构:

    MainModule.py
    libraries
     |- class_A.py
     |- processor.py
    

    __main__ 在processor.py中执行以创建 class_A (有数据)并腌制。

    processor.py中的代码

    import dill as pickle
    from class_A import Class_A
    
    data = 4
    instance_of_A = Class_A(data)
    
    path: str = r"C:\Users\ErikJ.GiesenLoo\Desktop\2023\EvdVds\instance_A.pkl"
    with open(path, "wb") as file:
        pickle.dump(instance_of_A, file)
    

    A类代码

    class Class_A:
        data = 0
        def __init__(self, data):
            self.data = data
    

    主模块中的代码:

    import dill as pickle
    from libraries.class_A import Class_A
    
    
    path: str = r"C:\Users\ErikJ.GiesenLoo\Desktop\2023\EvdVds\instance_A.pkl"
    with open(path, "rb") as file:
        instance_A = pickle.load(file)
    
        print(instance_A.data)
    

    MainModule.py然后尝试取消勾选保存的数据,但只有当我将class_A.py移出libraries文件夹时,取消勾选才有效。

    错误:

    ModuleNotFoundError: No module named 'class_A'
    
    0 回复  |  直到 1 年前
        1
  •  1
  •   juanpa.arrivillaga    1 年前

    所以你误解了文件的内容。“不在顶层”并不意味着一个子模块,它的意思是:

    def make_class():
        class A:
            pass
        return A
    
    A = make_class()
    a = A()
    

    虽然,我相信 dill 可能能够处理这个问题,但肯定是默认的 pickle 不会。

    您遇到的问题是没有打包您的项目,并且依赖于 default behavior of the directory of the script script being added to the module search path .

    libraries.class_a.Class_A class_a.Class_A .当你把你的课腌制时,它被认为是 class_A.Class_A 当你试图解开它时 没有这样的课吗 ,仅 libraries.class_A.Class_A .

    您应该打包并安装(可能是在可编辑模式下)您的项目。那么,您应该始终如一地使用导入。

    最懒惰的方法是明确设置Python。

    更改导入 processor.py 致:

     from libraries.class_A import Class_A
    

    然后,假设您的工作目录是包含以下内容的目录 MainModule.py ,您应该这样做:

    PYTHONPATH=. python libraries/processor.py
    

    要执行该脚本,您应该执行以下操作:

    PYTHONPATH=. python MainModule.py
    

    执行主脚本(虽然这不是真正必要的,但只是为了一致性)。