-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHow-to-use-super.py
More file actions
118 lines (86 loc) · 2.99 KB
/
Copy pathHow-to-use-super.py
File metadata and controls
118 lines (86 loc) · 2.99 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import collections
import logging
logging.basicConfig(level='INFO')
# --- 1. LoggingDict with super() ---
class LoggingDict(dict):
def __setitem__(self, key, value):
logging.info('Setting %r to %r' % (key, value))
super().__setitem__(key, value)
class LoggingOD(LoggingDict, collections.OrderedDict):
pass
ld = LoggingDict([('red', 1), ('green', 2), ('blue', 3)])
print(ld)
ld['red'] = 10
ld = LoggingOD([('red', 1), ('green', 2), ('blue', 3)])
print(ld)
ld['red'] = 10
print('-' * 20)
# --- 2. Show MRO Call Order ---
def show_call_order(cls, methname):
classes = [cls for cls in cls.__mro__ if methname in cls.__dict__]
print(' ==> '.join('%s.%s' % (cls.__name__, methname) for cls in classes))
show_call_order(LoggingOD, '__setitem__')
show_call_order(LoggingOD, '__iter__')
print('-' * 20)
# --- 3. Validate Call Order Requirements ---
position = LoggingOD.__mro__.index
assert position(LoggingDict) < position(collections.OrderedDict)
assert position(collections.OrderedDict) < position(dict)
# --- 4. Matching Argument Signatures ---
class Shape:
def __init__(self, *, shapename, **kwds):
self.shapename = shapename
super().__init__(**kwds)
class ColoredShape(Shape):
def __init__(self, *, color, **kwds):
self.color = color
super().__init__(**kwds)
cs = ColoredShape(color='red', shapename='circle')
# --- 5. Ensuring Root Exists ---
class Root:
def draw(self):
assert not hasattr(super(), 'draw')
class Shape(Root):
def __init__(self, *, shapename, **kwds):
self.shapename = shapename
super().__init__(**kwds)
def draw(self):
print('Drawing. Setting shape to:', self.shapename)
super().draw()
class ColoredShape(Shape):
def __init__(self, *, color, **kwds):
self.color = color
super().__init__(**kwds)
def draw(self):
print('Drawing. Setting color to:', self.color)
super().draw()
ColoredShape(color='blue', shapename='square').draw()
print('-' * 20)
# --- 6. Incorporating a Non-Cooperative Class ---
class Moveable:
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self):
print('Drawing at position:', self.x, self.y)
class MoveableAdapter(Root):
def __init__(self, *, x, y, **kwds):
self.moveable = Moveable(x, y)
super().__init__(**kwds)
def draw(self):
self.moveable.draw()
super().draw()
class MovableColoredShape(ColoredShape, MoveableAdapter):
pass
MovableColoredShape(color='red', shapename='triangle', x=10, y=20).draw()
print('-' * 20)
# --- 7. Complete Example: OrderedCounter ---
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
'Counter that remembers the order elements are first encountered'
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
def __reduce__(self):
return self.__class__, (OrderedDict(self),)
oc = OrderedCounter('abracadabra')
print(oc)