Python Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesPython Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old November 22nd, 2012, 11:06 AM
Alabaster Alabaster is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 7 Alabaster User rank is Just a Lowly Private (1 - 20 Reputation Level) 
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!

Reply With Quote
  #2  
Old November 23rd, 2012, 07:25 AM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,458 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 4 Days 6 h 26 m 43 sec
Reputation Power: 403
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!

Reply With Quote
  #3  
Old November 23rd, 2012, 02:00 PM
Alabaster Alabaster is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 7 Alabaster User rank is Just a Lowly Private (1 - 20 Reputation Level) 
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!

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > Re-instantiate shelved objects to access them with same syntax as pre-shelving?

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap