The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Python Programming
|
Re-instantiate shelved objects to access them with same syntax as pre-shelving?
Discuss Re-instantiate shelved objects to access them with same syntax as pre-shelving? in the Python Programming forum on Dev Shed. Re-instantiate shelved objects to access them with same syntax as pre-shelving? Python Programming forum discussing coding techniques, tips and tricks, and Zope related information. Python was designed from the ground up to be a completely object-oriented programming language.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

November 22nd, 2012, 11:06 AM
|
|
Registered User
|
|
Join Date: Nov 2012
Posts: 7
Time spent in forums: 2 h 28 m 54 sec
Reputation Power: 0
|
|
|
Re-instantiate shelved objects to access them with same syntax as pre-shelving?
Hello,
I have a script which does the following:
1. Parses a long csv file and creates several objects of various classes
2. Opens a GUI displaying these objects with various widgets for changing values
3. Serializes all the objects into a shelve data file.
I would like to be able to load the saved session and start at step 2 (using the shelved objects instead of re-parsing the csv file every time).
My GUI accesses all of the objects this way:
object.property
but when shelved, the objects are stored something like this:
my_shelve_db['LIST_OF_OBJECTS_CLASS1']
my_shelve_db['LIST_OF_OBJECTS_CLASS2']
Should I just do a for-loop through each list of objects and re-initialize them all? Is there a way to do this that is flexible (so that if I add properties in the future, I don't have to change the parsing code in two places -- the original csv parsing AND the shelve load parsing.
Or is there a more elegant way to restore shelved instances to their original instantiated state? (The objects are created dynamically through parsing the text file, so they don't have hard-coded names).
Thanks!
|

November 23rd, 2012, 07:25 AM
|
 |
Contributing User
|
|
|
|
|
Confused
Shelves have the same interface as dictionaries. To store an object you'd write
shelf['key'] = obj
where as you say this without an assignment: Quote:
but when shelved, the objects are stored something like this:
my_shelve_db['LIST_OF_OBJECTS_CLASS1'] |
Please provide an example of the problem using class c and no gui.
Code:
import shelve
class c:
pass
o = c()
o.attribute = 'changed value'
shelf = shelve.open('/tmp/shelf')
shelf['o'] = o
shelf.close()
del o
shelf = shelve.open('/tmp/shelf')
print('shelf.keys()):',shelf.keys())
o = shelf['o']
shelf.close()
print('dir(o):',dir(o))
print('o.attribute:',o.attribute)
__________________
[code] Code tags[/code] are essential for python code!
|

November 23rd, 2012, 02:00 PM
|
|
Registered User
|
|
Join Date: Nov 2012
Posts: 7
Time spent in forums: 2 h 28 m 54 sec
Reputation Power: 0
|
|
I may have answered my own question while trying to put together a sample script for you.
My objects are created dynamically through a parsing loop, so they don't have their own individual names (e.g. 'o' in your example) to call easily. So I couldn't assign the values as you recommended ( o = shelf['o'] ) without knowing every object ahead of time.
In my script, any time I edit an object, I do the following:
1. Iterate through a list of objects in that class (MyClass.ObjectList) using a classmethod (myobject = MyClass.FindByName(name)
2. Change the value that object using the object's method (e.g. myobject.ChangeValue(attribute, value)
It turns out that all I had to do was shelve MyClass.ObjectList (in addition to shelving the individual objects). Then upon loading the shelved data I could assign MyClass.ObjectList = shelf['myclass_objectlist']. I didn't think this would work without somehow shelving the methods as well. But it appears that as long as the class definitions are in the script, its methods will operate on shelved objects even if the objects were not instantiated in the current session. (At least this seems to be the case based on my experimenting -- correct me if I'm wrong).
Here is my sample code which seems to work. But I am a relative newbie to Python and OOP, so if you see any holes, potential issues, or something for which a better solution exists, I'd appreciate any advice:
Code:
### PYTHON 3 Grammar
import shelve
class c(object):
list_of_things = []
names_list = []
def __init__(self, name):
self.name = name
self.colorlist = []
self.data = {}
c.list_of_things.append(self)
c.names_list.append(self.name)
print('Initialized Thing:',self.name, self)
def ChangeValue(self, color, newvalue):
print('Original Value:',self.name, color, self.data[color])
self.data[color] = newvalue
print('Value changed:',self.name, color, self.data[color])
@classmethod
def FindThingByName(self, name_to_find):
for thing in c.list_of_things:
if thing.name == name_to_find:
return thing
################### SIMPLIFIED SIMULATION OF PARSING MY CSV FILE###
Contents_ParseFile = \
'Thing1,Blue,Schamobble\n\
Thing1,Green,Plumdiffoo\n\
Thing2,Yellow,Kwallabooble\n\
Thing2,Blue,Shoremilk\n\
Thing3,Purple,Stimkinzikle'
lines = Contents_ParseFile.split('\n')
for line in lines:
splitline = line.split(',')
name = splitline[0]
color = splitline[1]
nonsense = splitline[2]
if name not in c.names_list:
####### INITIALIZATION OF OBJECT CLASS c
thisthing = c(name)
######## OBJECTS HAVE NO PERMANENT VARIABLE NAMES
######## BECAUSE THEY ARE GENERATED DYNAMICALLY
######## FROM A CSV FILE WITH VARYING CONTENT
else:
######## (If thing already exists, do not initialize a new object)
thisthing = c.FindThingByName(name)
thisthing.colorlist.append(color)
thisthing.data[color] = nonsense
print(' => Updated value for',thisthing.name, color, nonsense)
#######################################################
def SimulateValueChange(name, color, newvalue):
'''Simple simulation of a value change that might occur in the GUI'''
mything = c.FindThingByName(name)
mything.ChangeValue(color,newvalue)
def SaveSession():
shelf = shelve.open('shelfdata')
# Shelve the list of things
shelf['thinglist'] = c.list_of_things
# Shelve the entire object using its unique name as the key:
for thing in c.list_of_things:
shelf[thing.name] = thing
print('\n++++++++++++++++++++++\nSession has been saved\n++++++++++++++++++++++')
shelf.close()
print('\n+++ Simulating a simple edit that might occur in the GUI:')
SimulateValueChange('Thing1','Blue','FoShizzle')
SaveSession()
#### Deleting /resetting data #########
for thing in c.list_of_things:
# resetting attributes for reasons in side question below
thing.name = ''
thing.colorlist = []
thing.data = {}
del(thing)
## side question - even after deleting, these objects still
## turn up when invoking c.FindByName class method???
## which is why I reset all the properties to blank values for
## the purpose of testing shelve
c.list_of_things = []
c.names_list = []
#######################################
shelf = shelve.open('shelfdata')
print('\n+++ Accessing value through shelf:',shelf['Thing1'].data['Blue'])
######### IT TURNS OUT THIS IS ALL I NEEDED TO ADD TO MY CODE ######
c.list_of_things = shelf['thinglist']
####################################################################
print('\n\n+++ Changing Value after opening shelf \n\
+++ (using same function as I used to access objects before shelving) +++\n')
try:
SimulateValueChange('Thing1','Blue','ThisIsMyNewValue')
except AttributeError:
print('\nError Accessing Shelved Object ')
shelf.close()
Thanks!
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|