Initial revision
This commit is contained in:
201
intern/python/modules/mcf/utils/hier_rx.py
Normal file
201
intern/python/modules/mcf/utils/hier_rx.py
Normal file
@@ -0,0 +1,201 @@
|
||||
'''
|
||||
Simple Hierarchic Walking functions for use with hierobj-type objects.
|
||||
|
||||
Provide for recurse-safe processing. Currently only provide depth-first
|
||||
processing, and don't provide means for ignoring branches of the tree
|
||||
during processing. For an example of breadth-first processing, see
|
||||
mcf.pars.int.index.indutils. For more complex hierarchic processing,
|
||||
see the mcf.walker package.
|
||||
|
||||
Originally these functions were only methods of the hierobj class (they
|
||||
still are methods of it). I've split them out to allow them to be
|
||||
imported selectively by other classes (some classes will only want
|
||||
the simple walking functions, and not want to be bothered with the
|
||||
methods which hierobj uses to keep track of its particular internal
|
||||
structures.
|
||||
'''
|
||||
|
||||
def hier_rapply(self, function,arglist=None,argdict={},moreattr = '__childlist__'):
|
||||
'''
|
||||
Safely apply a function to self and all children for
|
||||
the function's side effects. Discard the return values
|
||||
that function returns.
|
||||
|
||||
function
|
||||
function to apply
|
||||
arglist
|
||||
(self,)+arglist is the set of arguments passed to function
|
||||
argdict
|
||||
passed as namedargs to the function
|
||||
moreattr
|
||||
the attribute representing the children of a node
|
||||
'''
|
||||
alreadydone = {}
|
||||
tobedone = [self]
|
||||
if arglist or argdict:
|
||||
if not arglist: arglist=[self]
|
||||
else:
|
||||
arglist.insert(0,self) # we could insert anything... self is convenient
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
arglist[0]=object
|
||||
apply(function,tuple(arglist),argdict)
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
else: # no arglist or argdict
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
function(object)
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
def hier_rreturn(self, function,arglist=None,argdict={},moreattr = '__childlist__'):
|
||||
'''
|
||||
Safely apply a function to self and all children,
|
||||
collect the results in a list and return.
|
||||
|
||||
function
|
||||
function to apply
|
||||
arglist
|
||||
(self,)+arglist is the set of arguments passed to function
|
||||
argdict
|
||||
passed as namedargs to the function
|
||||
moreattr
|
||||
the attribute representing the children of a node
|
||||
'''
|
||||
alreadydone = {}
|
||||
tobedone = [self]
|
||||
results = []
|
||||
if arglist or argdict:
|
||||
if not arglist: arglist=[self]
|
||||
else:
|
||||
arglist.insert(0,self) # or anything you feel like
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
arglist[0]=object
|
||||
results.append(apply(function,tuple(arglist),argdict))
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
else:
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
results.append(function(object))
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
return results
|
||||
def hier_rgetattr(self, attrname, multiple=1, moreattr = '__childlist__'):
|
||||
'''
|
||||
Recursively collect the values for attrname and
|
||||
return as a list.
|
||||
|
||||
attrname
|
||||
attribute to collect
|
||||
arglist
|
||||
(self,)+arglist is the set of arguments passed to function
|
||||
argdict
|
||||
passed as namedargs to the function
|
||||
moreattr
|
||||
the attribute representing the children of a node
|
||||
'''
|
||||
alreadydone = {}
|
||||
tobedone = [self]
|
||||
results = []
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
try:
|
||||
if multiple:
|
||||
results.append(getattr(object, attrname))
|
||||
else:
|
||||
return getattr(object, attrname)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
return results
|
||||
def hier_rmethod(self, methodname,arglist=(),argdict={},moreattr = '__childlist__'):
|
||||
'''
|
||||
return the result of calling every object's method methodname,
|
||||
as for hier_rreturn otherwise.
|
||||
|
||||
methodname
|
||||
method to call
|
||||
arglist
|
||||
(self,)+arglist is the set of arguments passed to function
|
||||
argdict
|
||||
passed as namedargs to the function
|
||||
moreattr
|
||||
the attribute representing the children of a node
|
||||
'''
|
||||
|
||||
alreadydone = {}
|
||||
tobedone = [self]
|
||||
results = []
|
||||
while tobedone:
|
||||
object = tobedone[0]
|
||||
try:
|
||||
alreadydone[id(object)]
|
||||
# We've already processed this object
|
||||
except KeyError:
|
||||
# We haven't processed this object
|
||||
alreadydone[id(object)]=1
|
||||
try:
|
||||
results.append(apply(getattr(object,methodname),arglist,argdict))
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
tobedone[1:1]=getattr(object,moreattr)
|
||||
except AttributeError:
|
||||
# if the object isn't a hierobj, we don't need to recurse into it.
|
||||
pass
|
||||
del(tobedone[0])
|
||||
return results
|
||||
|
Reference in New Issue
Block a user