tags:

views:

155

answers:

2

I'm not sure why this Pickle example is not showing both of the dictionary definitions. As I understand it, "ab+" should mean that the pickle.dat file is being appended to and can be read from. I'm new to the whole pickle concept, but the tutorials on the net don't seem to go beyond just the initial storage.

import cPickle as pickle

def append_object(d, fname):
    """appends a pickle dump of d to fname"""
    print "append_hash", d, fname
    with open(fname, 'ab') as pickler:
        pickle.dump(d, pickler)

db_file = 'pickle.dat'

cartoon = {}
cartoon['Mouse'] = 'Mickey'
append_object(cartoon, db_file)

cartoon = {}
cartoon['Bird'] = 'Tweety'
append_object(cartoon, db_file)

print 'loading from pickler'
with open(db_file, 'rb') as pickler:
    cartoon = pickle.load(pickler)
print 'loaded', cartoon

Ideally, I was hoping to build up a dictionary using a for loop and then add the key:value pair to the pickle.dat file, then clear the dictionary to save some RAM.

What's going on here?

+3  A: 

I started to edit your code for readability and factored out append_object in the process.

There are multiple confusions here. The first, is that pickle.dump writes a Python object in its entirety. You can put multiple objects in a pickle file, but each needs its own load. The code did what you asked of it and loaded the first dictionary you wrote to the file. The second dictionary was there waiting to be read but it isn't a concatenation to the first, it is its own loadable.

Don't underestimate the importance of names. append_object isn't a great name, but it is different than append_to_object.

If you are opening a file for reading, just open it for reading and the same for writing or appending. Not only does it make your intentions more clear but it prevents silly errors.

msw
Thanks for putting my code into the block... I've been trying to figure that out. How do you do that? According to the reference, it looks like I just type a ' single quote character at the start and end of what I want to be in the code block. But that didn't work for me... =(
Brian
@Brian, you do that for code in line. For large blocks of code you add four spaces at the start of every line of code, or you can simply write the code without spaces, highlight it, and then click the "code sample" button which looks like 1's and 0's.
Wilduck
I'm still not quite sure how to revise the above code to hold both definitions within the pickle file...
Brian
+4  A: 

Don't use pickle for that. Use a database.

Python dbm module seems to fit what you want perfectly. It presents you with a dictionary-like interface, but data is saved to disk.

Example usage:

>>> import dbm
>>> x = dbm.open('/tmp/foo.dat', 'c')
>>> x['Mouse'] = 'Mickey'
>>> x['Bird'] = 'Tweety'

Tomorrow you can load the data:

>>> import dbm
>>> x = dbm.open('/tmp/foo.dat', 'c')
>>> print x['Mouse']
Mickey
>>> print x['Bird']
Tweety
nosklo
Oh my gosh!!! That dbm module looks awesome! Thank you so much!!!! I'm definitely going to give that a try!
Brian
Also note: According to the Python Website:"The dbm module has been renamed to dbm.ndbm in Python 3.0. The 2to3 tool will automatically adapt imports when converting your sources to 3.0."
Brian
Also, I just noticed that this is a module for Unix. I am coding under windows 7....
Brian
huh, sorry, you should still use the `dbm` module under pyhton 3, not `dbm.ndbm`. http://docs.python.org/py3k/library/dbm it works fine under windows.
nosklo