Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/env python 

class HierarchicalData(object):

    """
        organizes hierarchical data as a tree.
        for convenience inner nodes need not be constructed
        explicitly. see examples below.
    """

    def __init__(self):
        # self._d stores subtrees
        self._d = {}

    def __getattr__(self, name):
        # only attributes not starting with "_" are organinzed
        # in the tree
        if not name.startswith("_"):
            return self._d.setdefault(name, HierarchicalData())
        raise AttributeError("object %r has no attribute %s" % (self, name))

    def __getstate__(self): 
        # for pickling
        return self._d, self._attributes()

    def __setstate__(self, tp):
        # for unpickling
        d,l = tp
        self._d = d
        for name,obj in l: setattr(self, name, obj)

    def _attributes(self):
        # return 'leaves' of the data tree
        return [(s, getattr(self, s)) for s in dir(self) if not s.startswith("_") ]

    def _getLeaves(self, prefix=""):
        # getLeaves tree, starting with self
        # prefix stores name of tree node above
        prefix = prefix and prefix + "."
        rv = {}
        atl = self._d.keys()
        for at in atl:
            ob = getattr(self, at)
            trv = ob._getLeaves(prefix+at)
            rv.update(trv)
        for at, ob in self._attributes():
            rv[prefix+at] = ob
        return rv

    def __str__(self):
        # easy to read string representation of data
        rl = [] 
        for k,v in self._getLeaves().items():
            rl.append("%s = %s" %  (k,v))
        return "\n".join(rl)


def getLeaves(ob, pre=""): 
    """ getLeavess tree, returns dictionary mapping 
        paths from root to leafs to value of leafs 
    """
    return ob._getLeaves(pre)


if __name__=="__main__":
    
    model=HierarchicalData()

    # model.person is contstruted on the fly:
    model.person.surname = "uwe"
    model.person.name = "schmitt"
    model.number = 1

    print 
    print "access via attributes:"
    print
    print "model.person.surname=", model.person.surname
    print "model.person.name=", model.person.name
    print "model.number=", model.number
    print

    print "print complete model:"
    print
    print model
    print 

    import pickle

    o = pickle.loads(pickle.dumps(model))

    print "unpickle after pickle:"
    print
    print o
    print
    print "paths from root to leaves and values at leaves:"
    print 
    print getLeaves(o)

History

  • revision 2 (19 years ago)
  • previous revisions are not available