Potresti esaminare le monadi Reader o State; possono essere usati per condividere dati tra funzioni (pure, monadiche), senza ricorrere a parametri espliciti o simili.
C'è una serie di tutorial su F # per divertimento e profitto sulla monade di Stato (AKA Workflow in F # parlence). Ho anche fornito una descrizione in questa risposta SO che sembra abbastanza accessibile.
Esistono alcune implementazioni di altre monade in python che puoi anche fare riferimento, se devi implementare il tuo.
Molte persone (me compreso) trovano le monadi difficili all'inizio, quindi se non hai familiarità con il concetto, ti consiglio di guardare alcune delle monadi più semplici come Forse o Either, e quindi forse Reader o Writer, prima affrontare lo stato. Le implementazioni Python collegate sopra possono rendere le cose più chiare per te rispetto a quelle che probabilmente troverai altrove online (che probabilmente sarebbe Haskell).
Alcuni avvertimenti: c'è ancora un po 'di overhead sulle funzioni, dal momento che la monade è coinvolta, e questa deve essere usata con le funzioni ; Non penso che potresti farlo con i metodi di classe (anche se potrei sbagliarmi - non l'ho mai provato!)
UPDATE:
La pagina "monads in python" / lib ho linkato sopra in realtà fa ha un'implementazione monad di stato; controlla il codice a partire da ###### StateChanger Monad #########
per la definizione e gli esempi.
MODIFICA in risposta alla domanda nel commento:
Sì, è così che lo faresti - per essere più chiaro, gli argomenti con cui dichiari la funzione non dovrebbero includere le variabili di ambiente, solo quelle che la funzione avrebbe bisogno normalmente; le variabili di ambiente saranno accessibili tramite le funzioni monadico get
e set
.
Un esempio di Python che usa la notazione data nel link "monads in python" sopra:
@do(StateChanger) # <-- this makes makes it a stateful computation
def my_stateful_function1(arg):
# do something with 'arg' here
# then put it in the state:
yield dict_state_set(key, var_from_arg)
# I believe you can leave out 'mreturn' for this
@do(StateChanger)
def my_stateful_function2(arg1, arg2):
# something with 'arg1' here
# get the state chained via the monad:
state = yield get_state()
# do something else stateful:
yield my_stateful_function1(arg2)
# do something with 'state' dict here
# return; you have to use 'mreturn' instead of 'return':
mreturn(some_value)
Per eseguirlo chiameresti:
ret_val = my_stateful_function2("hello","world").run(initial_state_dict)
e il tuo valore di ritorno sarebbe una tupla:
(return_value_of_function, final_state_dict) = ret_val
Ricorda di usare yield
quando chiami altre funzioni stateful.
Ammonizione: fai attenzione a modificare lo stato delle tue funzioni poiché il tipo di dizionario Python è mutabile. È possibile ottenere e impostare le vars dello stato, nonché applicare una funzione (lambda) a loro; potresti desiderare di attenervisi piuttosto che tirare fuori lo stato e mutarlo volenti o nolenti.