1

I have gone through this website and many others but no one seems to give me the simplest possible answer. In the scrip bellow there are 2 different variables that need to be placed into a single pickle (aka 'test1' and 'test2'); but I am wholly unable to get even the simpler one of the two to load. There are no error messages or anything, and it does appear that something is being written to the pickle but then I close the 'program', re open it, try to load the pickle but the value of 'test1' does not change.

The second question is how to save both to the same pickle? at first i tried using the allStuff variable to store both test1 and test2 then dumping allStuff...the dump seems to be a success but loading does jack. Ive tried a variation where you list each file that should be loaded but this just caused a whole lot of errors and caused me to assault my poor old keyboard...

Please Help.

import pickle

class testing():

    test1 = 1000
    test2 = {'Dogs' : 0, 'Cats' : 0, 'Birds' : 0, 'Mive' : 0}


    def saveload():
            check = int(input(' 1. Save  :  2. Load  : 3. Print  : 4. Add'))
            allStuff = testing.test1, testing.test2
            saveFile = 'TestingSaveLoad.data'

            if check == 1:
                f = open(saveFile, 'wb')
                pickle.dump(testing.test1, f)
                f.close()
                print()
                print('Saved.')
                testing.saveload()


            elif check == 2:
                f = open(saveFile, 'rb')
                pickle.load(f)
                print()
                print('Loaded.')
                testing.saveload()        


            elif check == 3:
                print(allStuff)
                testing.saveload()

            else:
                testing.test1 += 234
                testing.saveload()


testing.saveload()
Arad Mann
  • 33
  • 6
  • 3
    What are you expecting to happen when you use [`pickle.load(f)`](http://docs.python.org/3/library/pickle.html#pickle.load)? It returns the reconstituted object and you aren't saving the return value. – thegrinner Sep 03 '13 at 15:45
  • As stated bellow, I believe my problem was that 'return' and 'assign', somehow appeared to me as the exact same thing. – Arad Mann Sep 04 '13 at 14:55

3 Answers3

1

The pickle.load documentation states:

Read a pickled object representation from the open file object file and return the reconstituted object hierarchy specified therein.

So you would need something like this:

testing.test1 = pickle.load(f)

However, to save and load multiple objects, you can use

# to save
pickle.dump(allStuff, f)

# to load
allStuff = pickle.load(f)
testing.test1, testing.test2 = allStuff
RazerM
  • 5,128
  • 2
  • 25
  • 34
1

Dump them as a tuple, and when loading, unpack the result back into the two variables.

pickle.dump((testing.test1,testing.test2), f)

and

testing.test1, testing.test2 = pickle.load(f)

Then change the print to print the two items and forget about allStuff, since you would have to keep updating allStuff every time you loaded/reassigned (depending on the type of item you are storing).

print(testing.test1, testing.test2)

I'd also remove the recursive call to saveLoad() and wrap whatever should be repeated in a while loop with an option to exit

if check == 0:
    break
Brian
  • 3,091
  • 16
  • 29
  • My first few attempts where very close to "pickle.dump((testing.test1,testing.test2), f)", except that I did not tuple them, this of course lead to the problem of to many arguments...and so on. I will also definitely consider the "if check == 0: break" idea. Thanks. – Arad Mann Sep 04 '13 at 14:31
1

You aren't saving the reconstituted pickled object currently. The documentation states that pickle.load() returns the reconstituted object.

You should have something like:

f = open(saveFile, 'rb')
testing.test1 = pickle.load(f)

To save multiple objects, use the approach recommended in this answer:

If you need to save multiple objects, you can simply put them in a single list, or tuple

Also, I recommend using the with keyword to open the file. That will ensure the file is closed even if something goes wrong. An example of a final output:

with open(saveFile, 'wb') as f:
    pickle.dump((testing1, testing2), f)

...

with open(saveFile, 'rb') as f:
    testing1, testing2 = pickle.load(f) # Implicit unpacking of the tuple

You might also want a while loop instead of the multiple calls to saveload() - it will be a bit cleaner. Note that right now you have no way out of your loop, short of quitting the program.

Community
  • 1
  • 1
thegrinner
  • 11,546
  • 5
  • 41
  • 64
  • As simple as that. I assumed that load() actually LOADS the files, because open(), well, opens them... But now upon rethinking the whole thing it is quite obvious that one should assign the stuff saved in the pickle to the variables in the script. I realize that my confusion is with the concept of 'return' vs 'assign'; in my mingled up cranium they appeared to be synonymous. Thanks a lot, this has cleared up a lot more than you might imagine. – Arad Mann Sep 04 '13 at 14:16