determining the number of output arguments
Peter Otten
__peter__ at web.de
Tue Nov 16 13:55:20 EST 2004
Jeremy Bowers wrote:
> On Tue, 16 Nov 2004 17:58:52 +0100, Peter Otten wrote:
>> You could yield Indent/Dedent (possibly the same class) instances
>> whenever the level changes - provided that the length of sequences of
>> nodes with the same depth does not approach one.
>
> In this case, the depth of the node is multiplied by some indentation
> parameter, or some similar operation, and it occurs in three or places, so
> the duplication of the
>
> if token == INDENT:
> depth += 1
> elif token == DEDENT:
> depth -= 1
> if depth == 0:
> abort or something
>
> three or four times was starting to smell itself.
I guess I don't understand, so I wrote a simple example:
DEDENT = object()
INDENT = object()
def _walk(items):
for item in items:
if isinstance(item, list):
yield INDENT
for child in _walk(item):
yield child
yield DEDENT
else:
yield item
class Tree(object):
def __init__(self, data):
self.data = data
def __iter__(self):
for item in _walk(self.data):
yield item
class WalkBase(object):
def __call__(self, tree):
dispatch = {
DEDENT: self.dedent,
INDENT: self.indent
}
default = self.default
for item in tree:
dispatch.get(item, default)(item)
class PrintIndent(WalkBase):
def __init__(self):
self._indent = ""
def indent(self, node):
self._indent += " "
def dedent(self, node):
self._indent = self._indent[:-4]
def default(self, node):
print self._indent, node
class PrintXml(WalkBase):
def indent(self, node):
print "<node>"
def dedent(self, node):
print "</node>"
def default(self, node):
print "<leaf>%s</leaf>" % node
def __call__(self, tree):
print "<tree>"
super(PrintXml, self).__call__(tree)
print "</tree>"
if __name__ == "__main__":
tree = Tree([
0,
[1, 2, 3],
[4,
[5, 6, 7],
[8, [9, 10]]],
[11],
12
])
for i, Class in enumerate([PrintIndent, PrintXml]):
print "%d " % i * 5
Class()(tree)
I think taking actions on indent/dedent "events" is easier and simpler than
keeping track of a numerical depth value, and at least the PrintXml example
would become more complicated if you wanted to infer the beginning/end of a
level from the change in the depth.
I do check the depth level twice (isinstance(item, list) and
dispatch.get()), but I think the looser coupling is worth it.
If you are looking for the cool version of such a dispatch mechanism,
Phillip J. Eby's article
http://peak.telecommunity.com/DevCenter/VisitorRevisited
(found in the Daily Python URL) might be interesting.
Peter
More information about the Python-list
mailing list