Re: code & function objects

Tim Peters (tim@ksr.com)
Thu, 07 Apr 94 00:38:05 -0400

I had no idea that code objects could be real useful for mere mortals
before Lance posted his example. Neat!

Jim, might this be of use in your quest for persistent objects?

The std Icon program library contains several routines for producing an
ASCII dump of arbitrary (including loopy) objects. The output I find
most readable is the kind that constructs a sequence of Icon expressions
that would, if executed, reproduce the original structure (up to pointer
isomorphism).

Icon doesn't have an 'eval', so that's usually a "read only" kind of
dump. But it looks easy to create an executable dump in Python!

E.g., session #1:

>>> L = [] # create a list with a loop
>>> L.append(L)
>>> type(L), len(L), L[0] is L
(<type 'list'>, 1, 1)
>>> from marshal import dumps
>>> code = 'L=[]\n' + 'L.append(L)\n' # build code to reproduce
>>> code = compile(code, '<L builder>', 'exec') # compile it
>>> f = open('Lbuilder','w')
>>> f.write( dumps(code) ) # write out the marshal'ed code
>>>

And session #2:

>>> from marshal import loads
>>> f = open('Lbuilder','r')
>>> dir() # just to show it really is a new session
['__name__', 'f', 'loads']
>>> exec loads(f.read()) # execute the old code
>>> dir() # and we've got the loopy list again
['L', '__name__', 'f', 'loads']
>>> type(L), len(L), L[0] is L
(<type 'list'>, 1, 1)
>>>

Seems this differs from the obvious technique of writing out the
"reproduce the object" code as a string, and exec'ing that string later,
in putting the compilation expense on the "write" end instead of the
"read" end. If reads outnumber writes, we probably win big. Probably
faster on the read end than any kind of crawl-over-an-object-descriptor-
and-rebuild-the-object-it-describes routine we could write in Python,
too.

fascinatedly y'rs - tim

Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp