classes vs dicts

David MacQuigg dmq at gain.com
Tue May 18 06:57:02 EDT 2004


On Thu, 13 May 2004 13:33:11 -0400, "Terry Reedy" <tjreedy at udel.edu>
wrote:

>"David MacQuigg" <dmq at gain.com> wrote in message
>news:nj57a01tqsvtufcur2gqu3enbjll5l95id at 4ax.com...
>> My problem is similar, with the additional requirement that I need a
>> convenient way to access data deep within a hierarchy of parameters.
>> I chose classes over dictionaries because the syntax to access items
>> in a deeply nested dictionary is awkward.
>>
>> dict[window1][plot2][xaxis][label][font][size] = 12
>>
>> vs
>>
>> statefiles.window1.plot2.xaxis.label.font.size = 12
>>
>> The problem is I can't easily save the whole hierarchy to disk.
>> Pickle doesn't work with classes.  Also, I worry about the overhead of
>> classes when I am just needing a simple container.  A typical
>> statefile will have 1000 parameters in 300 classes nested up to ten
>> levels deep.  As a structure of nested classes this takes about 74KB
>> on disk.  Importing the file creates a .pyc file that is 157KB !!  It
>> does seem to import quickly, however, so speed may not be a problem.
>
>I believe you could write a class whose instances would correspond to
>(wrap) a dictionary with possible subdicts.  It would have a getattribute
>method that turned the attribute name into a dict key and either return a
>new instance or a 'raw' object depending on whether the corresponding value
>was a nested dict or something else.  You would start with one instance
>representing the top level dict and work down from there.   I'll leave
>implementation to you.
>
>I also believe you could instead do this as a subclass of dict itself.  I
>might have even seen such somewhere.

I wrote a module, based on Dave Brueck's example, adding load and save
methods to his basic Bag class. The class definition is copied below.
The complete module, including unit tests is at
http://ece.arizona.edu/~edatools/Python/Statefiles/bag01.py

The work remaining is to make the output "statefile" an even neater,
more compact format.  This will allow a user to scan through thousands
of parameters to find the ones he needs, then cut-and-paste a section
of the parameter file into a script, and have the copied parameters
load into his program.

-- Dave

# Organize statefiles as nested "bags" of parameters.
# Load and save in a neat format for external editing.

TAB = 3; SP = ' '*(TAB-1); LINE = 0; LMAX = 15
TABMARKS = (('#'+SP)+('.'+SP)*4)*3 + '\n'

class Bag:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
        self.Indent = ''
        
    def load(infile):
        strng = infile.read()
        exec( 'bag = Bag(\n' + strng + ')' )
        return bag
    load = staticmethod(load)
    
    def save(self, outfile):
        global LINE
        for k,v in self.__dict__.items():
            if k == 'Indent': continue
            Idt = self.Indent
            if isinstance( v, Bag ):
                if LINE > LMAX:
                    outfile.write( TABMARKS ); LINE = 0
                outfile.write( Idt + k + '=Bag(\n' )
                LINE += 1
                v.Indent = Idt + ' '*TAB
                v.save(outfile)
                outfile.write( Idt + '),\n' )
            else:
                if type(v) is not str:
                    v = str(v)
                else:
                    v = "'%s'" % v
                outfile.write( Idt + k + ' = ' + v + ',\n' )
                LINE += 1




More information about the Python-list mailing list