Oggi ho scritto una piccola libreria pure-python esattamente per gestire le dipendenze aciclic negli attributi della classe python , noto anche come programmazione del flusso di dati . A volte non è possibile aggiornare semplicemente tutti gli attributi quando ne viene modificato uno. Idealmente, la modifica di un attributo non causa nessun aggiornamento. Solo ottenere un attributo dovrebbe causare aggiornamenti e solo gli aggiornamenti richiesti.
Questo è esattamente ciò che fa la biblioteca. È molto semplice da implementare in qualsiasi definizione di classe.
Ad esempio, considera una struttura di dipendenza degli attributi mostrata di seguito:
Questastrutturadidipendenzaècompletamentedefinitautilizzandoi descrittori della libreria
:
class DataflowSuccess():
# The following defines the directed acyclic computation graph for these attributes.
a1 = DependentAttr(1, [], None, 'a1')
a2 = DependentAttr(None, ['a1'], 'update_a2', 'a2')
a3 = DependentAttr(None, ['a2'], 'update_a3', 'a3')
a4 = DependentAttr(None, ['a1','a2'], 'update_a4', 'a4')
a5 = DependentAttr(None, ['a1','a2','a3','a6'], 'update_a5', 'a5')
a6 = DependentAttr(6, [], None, 'a6')
a7 = DependentAttr(None, ['a4','a5'], 'update_a7', 'a7')
# ...... define the update functions update_a2, update_a3 etc
def update_a2():
....
Gli argomenti forniti sopra al descrittore DependentAttr
sono il valore iniziale dell'attributo, i nomi degli attributi da cui dipende l'attributo, il nome della funzione membro responsabile dell'aggiornamento del suo valore e il nome dell'attributo.
La biblioteca si occupa di tutto il resto. La modifica di un attributo fa sì che i suoi figli (attributi che influisce) (e i loro figli, ecc.) Sappiano che i loro valori devono essere ricalcolati in futuro. Quando viene richiesto il valore di un attributo chiamando __get__
(ad esempio eseguendo obj.a5
), si verificano solo gli aggiornamenti richiesti, tutti automaticamente dietro le quinte.
Se non soddisfa le tue esigenze, almeno è un utile esempio di come funzionano le funzionalità dei descrittori. Questo esempio è disponibile nella pagina github I descrittori offrono molta flessibilità per modificare come __get__
e __set__
e __del__
lavora per gli attributi della tua classe, che possono risolvere i problemi di dipendenza.