visitor.py 938 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. """http://peter-hoffmann.com/2010/extrinsic-visitor-pattern-python-inheritance.html"""
  2. class Node(object):
  3. pass
  4. class A(Node):
  5. pass
  6. class B(Node):
  7. pass
  8. class C(A, B):
  9. pass
  10. class Visitor(object):
  11. def visit(self, node, *args, **kwargs):
  12. meth = None
  13. for cls in node.__class__.__mro__:
  14. meth_name = 'visit_' + cls.__name__
  15. meth = getattr(self, meth_name, None)
  16. if meth:
  17. break
  18. if not meth:
  19. meth = self.generic_visit
  20. return meth(node, *args, **kwargs)
  21. def generic_visit(self, node, *args, **kwargs):
  22. print('generic_visit ' + node.__class__.__name__)
  23. def visit_B(self, node, *args, **kwargs):
  24. print('visit_B ' + node.__class__.__name__)
  25. a = A()
  26. b = B()
  27. c = C()
  28. visitor = Visitor()
  29. visitor.visit(a)
  30. visitor.visit(b)
  31. visitor.visit(c)
  32. ### OUTPUT ###
  33. # generic_visit A
  34. # visit_B B
  35. # visit_B C