- Notifications
You must be signed in to change notification settings - Fork 7k
/
Copy pathflyweight_with_metaclass.py
63 lines (49 loc) · 1.68 KB
/
flyweight_with_metaclass.py
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
importweakref
classFlyweightMeta(type):
def__new__(mcs, name, parents, dct):
"""
Set up object pool
:param name: class name
:param parents: class parents
:param dct: dict: includes class attributes, class methods,
static methods, etc
:return: new class
"""
dct["pool"] =weakref.WeakValueDictionary()
returnsuper().__new__(mcs, name, parents, dct)
@staticmethod
def_serialize_params(cls, *args, **kwargs):
"""
Serialize input parameters to a key.
Simple implementation is just to serialize it as a string
"""
args_list=list(map(str, args))
args_list.extend([str(kwargs), cls.__name__])
key="".join(args_list)
returnkey
def__call__(cls, *args, **kwargs):
key=FlyweightMeta._serialize_params(cls, *args, **kwargs)
pool=getattr(cls, "pool", {})
instance=pool.get(key)
ifinstanceisNone:
instance=super().__call__(*args, **kwargs)
pool[key] =instance
returninstance
classCard2(metaclass=FlyweightMeta):
def__init__(self, *args, **kwargs):
# print('Init {}: {}'.format(self.__class__, (args, kwargs)))
pass
if__name__=="__main__":
instances_pool=getattr(Card2, "pool")
cm1=Card2("10", "h", a=1)
cm2=Card2("10", "h", a=1)
cm3=Card2("10", "h", a=2)
assert (cm1==cm2) and (cm1!=cm3)
assert (cm1iscm2) and (cm1isnotcm3)
assertlen(instances_pool) ==2
delcm1
assertlen(instances_pool) ==2
delcm2
assertlen(instances_pool) ==1
delcm3
assertlen(instances_pool) ==0