Skip to content

Instantly share code, notes, and snippets.

@nazavode
Last active March 12, 2017 14:26
Show Gist options
  • Save nazavode/a7fd359bee09cf6d1078955cfef9d80b to your computer and use it in GitHub Desktop.
Save nazavode/a7fd359bee09cf6d1078955cfef9d80b to your computer and use it in GitHub Desktop.
Snippets for Visitor pattern in Python
class AstNode(object):
pass
class Expression(AstNode):
pass
class BinOp(AstNode):
pass
class Add(BinOp):
pass
class Name(AstNode):
pass
class Num(AstNode):
pass
class OpVisitor(object):
@argdispatch('node')
def visit(self, node):
return '[{}]'.format(node)
@visit.register(Num)
def _(self, node):
return '[Num: {}]'.format(node)
@visit.register(Name)
def _(self, node):
return '[Name: {}]'.format(node)
@visit.register(BinOp)
def _(self, node):
return '[BinOp: {} {} {}]'.format(
self.visit(node.lhs),
self.visit(node.op),
self.visit(node.rhs)
)
# continue...
class OpVisitor(object):
def __init__(self):
self._dispatch_table = {
Name: self.visitName,
Num: self.visitNum,
BinOp: self.visit_BinOp,
}
def visit(self, node):
visit_fun = \
self._dispatch_table.get(node.__class__, self.visit_default)
return visit_fun(node)
# the same as in the previous example...
def visit(node):
if isinstance(node, Num):
return '[Num: {}]'.format(node)
elif isinstance(node, Name):
return '[Name: {}]'.format(node)
if isinstance(node, BinOp):
return '[BinOp: {} {} {}]'.format(
visit(node.lhs),
visit(node.op),
visit(node.rhs)
)
# continue...
class OpVisitor(object):
def visit(self, node):
fun_name = 'visit_' + node.__class__.__name__
fun = getattr(self, fun_name, self.visit_default)
return fun(node)
def visit_default(self, node):
return '[{}]'.format(node)
def visit_Num(self, node):
return '[Num: {}]'.format(node)
def visit_Name(self, node):
return '[Name: {}]'.format(node)
def visit_BinOp(self, node):
return '[BinOp: {} {} {}]'.format(
self.visit(node.lhs),
self.visit(node.op),
self.visit(node.rhs)
)
# continue...
class OpVisitor(object):
@singledispatch('node')
def visit(self, node):
return '[{}]'.format(node)
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment