pre-PEP: Simple Thunks

Ron_Adam radam2_ at _tampabay.rr.com
Tue Apr 19 02:25:36 EDT 2005


On Mon, 18 Apr 2005 21:11:52 -0700, Brian Sabbey
<sabbey at u.washington.edu> wrote:

>Ron_Adam wrote:
>> The load and dump would be private to the data class object. Here's a
>> more complete example.
>>
>> import pickle
>> class PickledData(object):
>> 	def __init__(self, filename):
>> 		self.filename = filename
>> 		self.L = None
>> 		try:
>> 			self._load()
>> 		except IOError:
>> 			self.L = []
>> 	def _load(self):
>> 		f = open(self.filename, 'r')
>> 		self.L = pickle.load(f)
>> 		f.close()
>> 	def _update(self):
>> 		f = open(self.filename, 'w')
>> 		pickle.dump(self.L, f)
>> 		f.close()
>> 	def append(self, record):
>> 		self.L.append(record)
>> 		self._update()
>> 	# add other methods as needed ie.. get, sort, clear, etc...
>>
>> pdata = PickledData('filename')
>>
>> pdata.append('more data')
>> pdata.append('even more data')
>>
>> print pdata.L
>> ['more data', 'even more data']
>>
>>
>>> This has the same issues as with opening and closing files:  losing the
>>> 'dump', having to always use try/finally if needed, accidentally
>>> re-binding 'p', significantly more lines.  Moreover, class 'Pickled' won't
>>> be as readable as the 'pickled_file' function above since 'load' and
>>> 'dump' are separate methods that share data through 'self'.
>>
>> A few more lines to create the class, but it encapsulates the data
>> object better. It is also reusable and extendable.
>
>This class isn't reusable in the case that one wants to pickle something 
>other than an array.  Every type of object that one would wish to pickle 
>would require its own class.

...Or in a function, or the 3 to 6 lines of pickle code someplace.
Many programs would load data when they start, and then save it when
the user requests it to be saved.  So there is no one method fits all
situations.  Your thunk example does handle some things better.


Here's yet another way to do it, but it has some limitations as well.

import pickle
def pickle_it(filename, obj, commands):
    try:
        f = open(filename, 'r')    
        obj = pickle.load(f)
        f.close()
    except IOError:
        pass 	
    for i in commands:
        i[0](i[1])
    f = open(filename, 'w')
    pickle.dump(obj, f)
    f.close()
 
file = 'filename'
L = []

opps = [ (L.append,'more data'),
         (L.append,'even more data') ]
pickle_it(file, L, opps)


>Also, this implementation behaves differently because the object is 
>re-pickled after every modification.  This could be a problem when writing 
>over a network, or to a shared resource.
>
>-Brian

In some cases writing to the file after ever modification would be
desired.  A way around that would be to use a buffer of some sort. But
then again, that adds another level of complexity and you would have
to insure it's flushed at some point which get's back to the issue of
not closing a file. 

Thanks for explaining how thunks works.  I'm still undecided on
whether it should be built in feature or not. 

I would rather have a way to store a block of code and pass it to a
function, then execute it at the desired time.  That would solve both
the issue where you would use a thunk, and replace lambdas as well.
But I understand there's a lot of resistance to that because of the
potential abuse.

Cheers,
Ron




More information about the Python-list mailing list