Skip to content

Instantly share code, notes, and snippets.

@danoneata
Last active November 20, 2015 12:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danoneata/1ec16a1ffec242fc714e to your computer and use it in GitHub Desktop.
Save danoneata/1ec16a1ffec242fc714e to your computer and use it in GitHub Desktop.
Binary methods using the visitor pattern
class Expr(object):
def accept(self, visitor):
method_name = 'visit_{}'.format(self.__class__.__name__.lower())
visit = getattr(visitor, method_name)
return visit(self)
class Int(Expr):
def __init__(self, value):
self.value = value
def __str__(self):
return 'Int {}'.format(self.value)
class Str(Expr):
def __init__(self, value):
self.value = value
def __str__(self):
return 'Str {}'.format(self.value)
class Visitor(object):
pass
class IntAdd(Visitor):
def __init__(self, i):
self.i = i
def visit_int(self, i):
return Int(int(self.i.value) + int(i.value))
def visit_str(self, s):
return Str(str(self.i.value) + str(s.value))
class StrAdd(Visitor):
def __init__(self, s):
self.s = s
def visit_int(self, i):
return Str(str(self.s.value) + str(i.value))
def visit_str(self, s):
return Str(str(self.s.value) + str(s.value))
class AddVisitor(Visitor):
def __init__(self, expr):
self.expr = expr
def visit_int(self, i):
return self.expr.accept(IntAdd(i))
def visit_str(self, s):
return self.expr.accept(StrAdd(s))
def add(a, b):
return a.accept(AddVisitor(b))
def main():
print(add(Int(4), Int(5)))
print(add(Str(4), Int(5)))
print(add(Int(4), Str(5)))
print(add(Str(4), Str(5)))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment