Базовый подход будет использовать встроенные типы данных. Если я получу ваш дрейф, объект Letter
должен быть создан на фабрике с кэшем dict
, чтобы сохранить ранее сгенерированные объекты Letter
. Фабрика создаст только один Letter
объект для каждого ключа.
Объект Number
может быть подклассом list
, который будет содержать объекты Letter
, так что append()
может использоваться для добавления потомка. A list
легко ориентироваться.
Грубый план кеширующей фабрики:
>>> class Letters(object):
... def __init__(self):
... self.cache = {}
... def create(self, v):
... l = self.cache.get(v, None)
... if l:
... return l
... l = self.cache[v] = Letter(v)
... return l
>>> factory=Letters()
>>> factory.cache
{}
>>> factory.create('a')
<__main__.Letter object at 0x00EF2950>
>>> factory.create('a')
<__main__.Letter object at 0x00EF2950>
>>>
Чтобы выполнить требование 6 (конструктор), вот
более надуманный пример, использующий __new__
конструктора кэширования. Это похоже на Рецепт 413717: Создание объекта кэширования .
class Letter(object):
cache = {}
def __new__(cls, v):
o = cls.cache.get(v, None)
if o:
return o
else:
o = cls.cache[v] = object.__new__(cls)
return o
def __init__(self, v):
self.v = v
self.refcount = 0
def addAsChild(self, chain):
if self.refcount > 0:
return False
self.refcount += 1
chain.append(self)
return True
Проверка работоспособности кеша
>>> l1 = Letter('a')
>>> l2 = Letter('a')
>>> l1 is l2
True
>>>
Для принудительного использования одного родителя вам понадобится метод для Letter
объектов (не Number
) - со счетчиком ссылок. При вызове для добавления он будет отклонять добавление, если счетчик больше нуля.
l1.addAsChild(num4)