Skip to content

Commit 027e6e7

Browse files
committed
Merge branch 'prawn-cake-master'
2 parents 18a6cd2 + 2924b30 commit 027e6e7

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

flyweight.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@
66
import weakref
77

88

9+
class FlyweightMeta(type):
10+
def __new__(mcs, name, parents, dct):
11+
"""
12+
13+
:param name: class name
14+
:param parents: class parents
15+
:param dct: dict: includes class attributes, class methods,
16+
static methods, etc
17+
:return: new class
18+
"""
19+
20+
# set up instances pool
21+
dct['pool'] = weakref.WeakValueDictionary()
22+
return super(FlyweightMeta, mcs).__new__(mcs, name, parents, dct)
23+
24+
@staticmethod
25+
def _serialize_params(cls, *args, **kwargs):
26+
"""Serialize input parameters to a key.
27+
Simple implementation is just to serialize it as a string
28+
29+
"""
30+
args_list = map(str, args)
31+
args_list.extend([str(kwargs), cls.__name__])
32+
key = ''.join(args_list)
33+
return key
34+
35+
def __call__(cls, *args, **kwargs):
36+
key = FlyweightMeta._serialize_params(cls, *args, **kwargs)
37+
pool = getattr(cls, 'pool', {})
38+
39+
instance = pool.get(key)
40+
if not instance:
41+
instance = super(FlyweightMeta, cls).__call__(*args, **kwargs)
42+
pool[key] = instance
43+
return instance
44+
45+
946
class Card(object):
1047

1148
"""The object pool. Has builtin reference counting"""
@@ -27,6 +64,15 @@ def __new__(cls, value, suit):
2764
def __repr__(self):
2865
return "<Card: %s%s>" % (self.value, self.suit)
2966

67+
68+
class Card2(object):
69+
__metaclass__ = FlyweightMeta
70+
71+
def __init__(self, *args, **kwargs):
72+
# print('Init {}: {}'.format(self.__class__, (args, kwargs)))
73+
pass
74+
75+
3076
if __name__ == '__main__':
3177
# comment __new__ and uncomment __init__ to see the difference
3278
c1 = Card('9', 'h')
@@ -42,6 +88,25 @@ def __repr__(self):
4288
c3 = Card('9', 'h')
4389
print(hasattr(c3, 'temp'))
4490

91+
# Tests with metaclass
92+
instances_pool = getattr(Card2, 'pool')
93+
cm1 = Card2('10', 'h', a=1)
94+
cm2 = Card2('10', 'h', a=1)
95+
cm3 = Card2('10', 'h', a=2)
96+
97+
assert (cm1 == cm2) != cm3
98+
assert (cm1 is cm2) is not cm3
99+
assert len(instances_pool) == 2
100+
101+
del cm1
102+
assert len(instances_pool) == 2
103+
104+
del cm2
105+
assert len(instances_pool) == 1
106+
107+
del cm3
108+
assert len(instances_pool) == 0
109+
45110
### OUTPUT ###
46111
# (<Card: 9h>, <Card: 9h>)
47112
# (True, True)

0 commit comments

Comments
 (0)