Sto scrivendo una libreria per lavorare con tipi speciali di alberi, chiamati alberi Foo . Un albero Foo ha una struttura molto speciale. Esistono alcune operazioni, chiamate bar e baz , che hanno senso solo sugli alberi Foo . Quindi sto progettando una classe FooTree
per rappresentare gli alberi Foo .
Per costruire un'istanza FooTree
, si potrebbe passare qualche oggetto che rappresenta un albero. Questo oggetto verrà controllato per la struttura speciale e memorizzato internamente:
class FooTree(object):
def __init__(self, tree):
... # check that tree is a valid Foo tree
self._tree = tree
def bar(self):
# operation that only makes sense on a foo tree
Il problema è: cosa succede se costruisco un FooTree
da un oggetto mutabile? Ad esempio, supponiamo che Tree
sia un tipo le cui istanze siano mutabili:
tree = Tree()
... # build a valid Foo tree
foo_tree = FooTree(tree)
tree.remove_node(0) # tree is no longer a Foo tree
Poiché tree
non è più un albero Foo valido e foo_tree
racchiude un riferimento a tree
, foo_tree
non è più valido.
Invece potrei copiare l'albero quando creo un FooTree
:
class FooTree(object):
def __init__(self, tree):
... # check that tree is a valid Foo tree
self._tree = tree.copy()
def bar(self):
# operation that only makes sense on a foo tree
Questo risolve il problema, ma ne crea uno nuovo: gli alberi Foo sono in genere molto grandi, quindi copiarli è costoso.
Quali sono i modelli per la creazione di oggetti FooTree
da oggetti Tree
, senza copiare e senza il problema di mutevolezza?
Ad esempio, potrei avere FooTree
accettare un callable che produce un Tree
:
class FooTreeBuilder(object):
def __init__(self, data):
self.data = data
def __call__(self):
tree = Tree()
... # build tree from self.data
return tree
class FooTree(object):
def __init__(self, builder):
self._tree = builder()
builder = FooTreeBuilder(data)
foo_tree = FooTree(builder)
Ci sono approcci migliori? Sono specificamente alla ricerca di approcci che ben si prestano alle implementazioni di Python.