Load pickled object in different file - Attribute error

前端 未结 2 1064
名媛妹妹
名媛妹妹 2021-02-02 10:30

I have some trouble with loading a pickled file in a module that is different from the module where I pickled the file. I am aware of the following thread: Unable to load files

相关标签:
2条回答
  • 2021-02-02 10:53

    in your class_def.py file you have this code:

    if __name__ == '__main__':
        doc = Document()
        utils.save_document(doc)
    

    This means that doc will be a __main__.Document object, so when it is pickled it is expecting to be able to get a Document class from the main module, to fix this you need to use the definition of Document from a module called class_def meaning you would add an import here:

    (in general you can just do from <own module name> import * right inside the if __name__ == "__main__")

    if __name__ == '__main__':
        from class_def import Document 
        # ^ so that it is using the Document class defined under the class_def module
        doc = Document()
        utils.save_document(doc)
    

    that way it will need to run the class_def.py file twice, once as __main__ and once as class_def but it does mean that the data will be pickled as a class_def.Document object so loading it will retrieve the class from the correct place. Otherwise if you have a way of constructing one document object from another you can do something like this in utils.py:

    def save_document(doc):
        if doc.__class__.__module__ == "__main__":
            from class_def import Document #get the class from the reference-able module
            doc = Document(doc) #convert it to the class we are able to use
    
    
        write_file = open(file_path, 'wb')
        pickle.dump(doc, write_file)
    

    Although usually I'd prefer the first way.

    0 讨论(0)
  • 2021-02-02 11:06

    I had a similar problem and only just realized the differences between our implementations.

    Your file structure:

    • util.py
      • define pickle functions
    • class_def.py
      • import util
      • define class
      • make instance
      • call save pickle
    • process.py
      • import util
      • load pickle

    My mistake (using your file names) was first:

    • util_and_class.py
      • define class
      • define pickle funcs
      • make instance
      • call save pickle
    • process.py
      • import util_and_class
      • call load pickle << ERROR

    What solved my pickle import problem:

    • util_and_class.py
      • define class
      • define pickle funcs
    • pickle_init.py
      • import util_and_class
      • make instance
      • call save pickle
    • process.py
      • call load pickle

    This had the welcomed side effect that I didn't need to import the util_and_class file as it's baked into the pickle file. Calling the instance and saving the pickle in a separate file resolved the __name__ issue of "loading a pickled file in a module that is different from the module where I pickled the file."

    0 讨论(0)
提交回复
热议问题