Pickle Encoding Errors

D

Dan

To demonstrate the problem I have written the following program:

___________________________________ Code Start
________________________________
import pickle

destruct=1

class PickleTest:
library={}

def __init__(self):
self.unpickle()
def __del__(self):
if destruct:
print "Pickling from destructor..."
self.pickle()

def unpickle(self):
try:
f=open("pickle.txt")
self.library=pickle.load(f)
f.close()
print "Unpickled just fine"
except:
print "Error unpickling"
self.library={u"A": 1,
u"B": 2,
u"C": 3}

def pickle(self):
f=open("pickle.txt","w")
pickle.dump(self.library,f)
f.close()
print "Pickled just fine"

if __name__=="__main__":
pt=PickleTest()
if not destruct:
print "Pickling from __main__..."
pt.pickle()
___________________________________ Code End
________________________________

Running the program with "pickle.txt" not created and destruct=1
generates the following output:

Error unpickling
Pickling from destructor...
Exception exceptions.LookupError: 'unknown encoding: raw-unicode-
escape' in <bound method PickleTest.__del__ of <__main__.PickleTest
instance at 0xb7d3decc>> ignored

If I now change destruct to 0 the output is:

Error unpickling
Pickling from __main__...
Pickled just fine

Even more odd is that with an existing "pickle.txt" and destruct set
to 1 it seems to work correctly:

Unpickled just fine
Pickling from destructor...
Pickled just fine



I'm running Python 2.5.4 on Debian Sid.

If anybody understands the error please enlighten me.

Dan
 
D

Dan

__del__ is called in an indeterministic order. Most of the Python
environment is already gone when your __del__ method is called. The
pickle module doesn't have enough bits left to fulfill its job.

Christian

Thank you both for your advice. Python is very new to me so still
plenty to learn.
I still think it's interesting that once the file exists there is no
error generated but at least I know how it should be done.
 
L

Laszlo Nagy

I'm running Python 2.5.4 on Debian Sid.

If anybody understands the error please enlighten me.

Very interesting! Here is a minimalist version:

import pickle
class PickleTest:
def __init__(self):
self.library={u"A": 1,u"B": 2,u"C": 3}
def __del__(self):
self.pickle()
def pickle(self):
pickle.dumps(self.library)
pt=PickleTest()

However, the exception is not thrown if dictionary keys are not
unicodes. cPickle version is even more strange:

import cPickle
class PickleTest:
def __init__(self):
self.library={u"A": 1,u"B": 2,u"C": 3}
def __del__(self):
self.pickle()
def pickle(self):
cPickle.dumps(self.library)

pt=PickleTest()

Result:

Exception AttributeError: "'NoneType' object has no attribute 'dumps'"
in <bound
method PickleTest.__del__ of <__main__.PickleTest instance at
0x00CC1F08>> ignored

Of course the error is gone if you do this:

if __name__ == "__main__":
pt=PickleTest()
del pt # No more references to object, will be destroyed before the
main program starts exiting.

You should NOT write files from object destructors anyway. You can never
know when an object willl be destroyed. The correct way to implement
this is to put it in try - finally

pt=PickleTest()
try:
do_something_with(pt)
finally:
pt.pickle()

Best.

Laszlo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top