saving and reloading variables for interactive work

D

Darren Dale

If I am working interactively with 10 variables and wanted to pickle
them and reload them tomorrow using the same variable names, would there
be a direct way of doing it?

Thanks,
Darren
 
C

Christopher T King

If I am working interactively with 10 variables and wanted to pickle
them and reload them tomorrow using the same variable names, would there
be a direct way of doing it?

Reminds me of my days in AppleSoft BASIC :)

Unfortunately, there is no quick & easy way to do this in Python, since
there is no easy way to differentiate unpicklable things (such as modules
and functions) from picklable ones (your variables), nor to make Pickle
gracefully ignore such objects. If you can get all your variable names
into a list, however, you could use this code:
foo = 5
bar = 6
myvars = ['foo','bar']
import pickle
pickle.dump(dict([(n,vars()[n]) for n in myvars]),open('myvars','w'))

[time passes]
6

Pythonistas will cringe at my gratuitous use of vars(), but Python
currently provides no method of using getattr()/setattr() to get/set
module-level variables. getattr(__main__,...), anyone?
 
D

Darren Dale

Unfortunately, there is no quick & easy way to do this in Python, since
there is no easy way to differentiate unpicklable things (such as modules
and functions) from picklable ones (your variables), nor to make Pickle
gracefully ignore such objects. If you can get all your variable names
into a list, however, you could use this code:

Could you determine the picklable types using something like this? Its
kinda ugly, but maybe something related would work:

myvars = {}
for key in vars().keys():
myvar = vars()[key]
if str(type(myvar)) == "<type 'module'>": pass
elif: str(type(myvar)) == "<type 'function'>": pass
elif: str(type(myvar)) == "<type 'unpicklable'>": pass
else: myvars.update({key:myvar})

pickle.dump(myvars,open('myvars','wb'),-1)


Maybe a try/except would be appropriate, but the pickle docs ay that an
unspecified number of bytes may have been written to the file before the
PicklingError exception is raised.

Further comments would be greatly appreciated.
 
C

Christopher T King

Could you determine the picklable types using something like this? Its
kinda ugly, but maybe something related would work:

myvars = {}
for key in vars().keys():
myvar = vars()[key]
if str(type(myvar)) == "<type 'module'>": pass
elif: str(type(myvar)) == "<type 'function'>": pass
elif: str(type(myvar)) == "<type 'unpicklable'>": pass
else: myvars.update({key:myvar})

You can do this a bit more directly using the types module to check the
types (with a little bit of code restructuring):

from types import *
myvars = {}
for key,myvar in vars().items():
if not isinstance(myvar,(ModuleType,FunctionType)):
myvars[key]=myvar

A list comprehension would get you a nice, unreadable one-liner if it's so
desired:

from types import *
myvars = dict([(key,myvar) for key,myvar in vars().items() \
if not isinstance(myvar,(ModuleType,FunctionType))])

The problem with these types is there's no real guarantee what can be
pickled and what can't, and of those things that can be pickled, what
makes sense (functions can be pickled, but their code isn't stored).
There's currently no ispicklable() function
Maybe a try/except would be appropriate, but the pickle docs ay that an
unspecified number of bytes may have been written to the file before the
PicklingError exception is raised.

You could use dumps() instead of dump() for testing picklability before
picklation, though it smells of hackishness:

def ispicklable(item):
try:
pickle.dumps(item)
except PicklingError:
return False
return True

Then you can just use ispicklable() in place of the 'not isinstance()'
mess I wrote.

I've done some poking though, and there a better way than that. It seems
all picklable objects define a __reduce__ method, so you could generalize
this check like this:

def ispicklable(item):
try:
item.__reduce__()
except KeyError,TypeError:
return False
return True

Dunno if any of this helps; sorry if parts make no sense, I've retyped
parts of this a couple times :p
 
D

Darren Dale

I've done some poking though, and there a better way than that. It seems
all picklable objects define a __reduce__ method, so you could generalize
this check like this:

def ispicklable(item):
try:
item.__reduce__()
except KeyError,TypeError:
return False
return True

I think this may only be true for new-style classes, or objects that
pickle "is unfamiliar with". I tried calling this method for strings,
dicts, lists, and it complains that these are all unpicklable.
object().__reduce__() does work though.

I'll give it some thought.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top