# HG changeset patch # User Paul Boddie # Date 1484953393 -3600 # Node ID 26dcaef4d7a9f33bfa310b32b5bdf5569bca4b14 # Parent 6ab1b9e4be06e6a137a97c05d0653aee6fedbf21 Added a demonstration of getattr involving a visitor-like object dispatching to methods by using name attributes present on node objects from an expression node tree to identify those methods. diff -r 6ab1b9e4be06 -r 26dcaef4d7a9 tests/getattr_visitor.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/getattr_visitor.py Sat Jan 21 00:03:13 2017 +0100 @@ -0,0 +1,104 @@ +class Expr: + + "An expression." + + name = "Expr" + + def __init__(self, ops): + self.ops = ops + + def children(self): + return self.ops + +class Binary: + + "A binary operator." + + name = "Binary" + + def __init__(self, left, op, right): + self.left = left + self.op = op + self.right = right + + def children(self): + return self.left, self.right + +class Unary: + + "A unary operator." + + name = "Unary" + + def __init__(self, op, operand): + self.op = op + self.operand = operand + + def children(self): + return self.operand, + +class Value: + + "A general value." + + name = "Value" + + def __init__(self, value): + self.value = value + + def children(self): + return () + +class Visitor: + + "Visit nodes in an expression tree." + + def __init__(self): + self.indent = 0 + + def visit(self, node): + + # Obtain the method for the node name. + + fn = getattr(self, node.name) + + # Call the method. + + fn(node) + + # Visit the node's children. + + self.visitChildren(node) + + def visitChildren(self, node): + self.indent += 1 + for n in node.children(): + self.visit(n) + self.indent -= 1 + + def writeIndent(self): + i = 0 + while i < self.indent: + print "", + i += 1 + + def Expr(self, node): + self.writeIndent() + print "Expression..." + + def Binary(self, node): + self.writeIndent() + print "Binary operation", node.op + + def Unary(self, node): + self.writeIndent() + print "Unary operation", node.op + + def Value(self, node): + self.writeIndent() + print "Value", node.value + +# Test the visitor with an example expression. + +expr = Expr([Binary(Value(1), "+", Binary(Unary("-", Value(2)), "*", Value(3)))]) +Visitor().visit(expr)