forked from tuvo1106/python_design_patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclassic.py
More file actions
91 lines (64 loc) · 2.03 KB
/
classic.py
File metadata and controls
91 lines (64 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# taken from https://tavianator.com/the-visitor-pattern-in-python/
def _qualname(obj):
"""Get the fully-qualified name of an object (including module)."""
return obj.__module__ + '.' + obj.__qualname__
def _declaring_class(obj):
"""Get the name of the class that declared an object."""
name = _qualname(obj)
return name[:name.rfind('.')]
# Stores the actual visitor methods
_methods = {}
# Delegating visitor implementation
def _visitor_impl(self, arg):
"""Actual visitor method implementation."""
method = _methods[(_qualname(type(self)), type(arg))]
return method(self, arg)
# The actual @visitor decorator
def visitor(arg_type):
"""Decorator that creates a visitor method."""
def decorator(fn):
declaring_class = _declaring_class(fn)
_methods[(declaring_class, arg_type)] = fn
# Replace all decorated methods with _visitor_impl
return _visitor_impl
return decorator
# ↑↑↑ LIBRARY CODE ↑↑↑
class DoubleExpression:
def __init__(self, value):
self.value = value
def accept(self, visitor):
visitor.visit(self)
class AdditionExpression:
def __init__(self, left, right):
self.left = left
self.right = right
def accept(self, visitor):
visitor.visit(self)
class ExpressionPrinter:
def __init__(self):
self.buffer = []
@visitor(DoubleExpression)
def visit(self, de):
self.buffer.append(str(de.value))
@visitor(AdditionExpression)
def visit(self, ae):
self.buffer.append('(')
ae.left.accept(self)
self.buffer.append('+')
ae.right.accept(self)
self.buffer.append(')')
def __str__(self):
return ''.join(self.buffer)
if __name__ == '__main__':
# represents 1+(2+3)
E = AdditionExpression(
DoubleExpression(1),
AdditionExpression(
DoubleExpression(2),
DoubleExpression(3)
)
)
BUFFER = []
printer = ExpressionPrinter()
printer.visit(E)
print(printer)