2017-12-09 3 views
0

Ich verwende die pytranstions-Bibliothek, um endliche Automaten zu bauen.So speichern Sie eine pytransitions-Maschine in einer YAML-Konfigurationsdatei

Viele Anwender die Speicherung der Konfigurations der Maschine als YAML Datei kann als in den Antworten von @wtgee und @limdautohere und here gesehen werden.

Jetzt kann ich sehen, wie man eine YAML-Datei zum Speichern von Zuständen und Transitionen erstellen würde. Allerdings bin ich mir nicht sicher, wie man auch die mit dem FSM verbundenen Funktionen in einer YAML-Datei speichern würde.

Könnte mir jemand zeigen, wie man das macht?

Antwort

0

Ich bin mir nicht bewusst eine bequeme Möglichkeit, das tatsächliche Modell und seine Funktion in YAML/JSON zu speichern. Ich gehe davon aus, dass der Workflow Sie gerade erwähnt die Funktionsnamen in JSON wie folgt speichert:

{  
    "states": ["A", "B", "C"], 
    "initial": "A", 
    "transitions": [ 
    {"trigger": "go", "source": "A", "dest": "B", "after": "func_A"}, 
    {"trigger": "go", "source": "B", "dest": "C", "after": "func_B"} 
    ] 
} 

oder YAML:

--- 
initial: A 
states: 
    - A 
    - B 
    - C 
transitions: 
    - 
    after: func_A 
    dest: B 
    source: A 
    trigger: go 
    - 
    after: func_B 
    dest: C 
    source: B 
    trigger: go 

Wenn Sie Rückrufe als Strings gespeichert werden sie den Moment ausgewertet werden, das Ereignis (In diesem Fall wird go) ausgelöst. Nehmen wir an, wir haben JSON/YAML oben in ein Python-Dictionary namens d geladen. Wenn die dict Tasten sind identisch mit transitions Schlüsselwörter, können Sie ein Modell wie folgt initialisieren:

from transitions import Machine 
class Model: 

    def func_A(self): 
     print("func A") 

    def func_B(self): 
     print("func B") 


model = Model() 
m = Machine(model, **d) 
model.go() 
model.go() 

Sie könnten ein Beschreibungsfeld model zu Ihrem YAML hinzufügen, die ‚die Modellklasse zu laden (zB gibt module.models.TestModel ') und importieren Sie die Modelldefinition dynamically mit importlib. Oder Sie können das erforderliche Modell implizit definieren (z. B. REST-Endpunkt '/ TestModel' initialisiert ein Testmodell). Wenn Sie wirklich in YAML Ihre Modellklassendefinition speichern möchten, können Sie die Klassendefinition mit Gurke/Dill serialise:

d["model"] = pickle.dumps(Model) 
SerialisedModel = pickle.loads(d.pop("model")) 
model = SerialisedModel() 
m = Machine(model, **d) 

Wenn Sie den aktuellen Zustand nur speichern möchten, können Sie Ihre Machine Instanz direkt serialise können:

d["machine_object"] = pickle.dumps(m) 

Dies ist jedoch weniger transparent als der vorherige Ansatz. In jedem Fall sollten Sie Callbacks nicht mit Funktionsreferenzen definieren, da dies später zu Problemen führen kann. Vielleicht kann pickle/dill auch damit umgehen, aber ich würde nicht darauf zählen.

Ausgereiftere Lösungen wurden von Dave Kuhlmann here vorgeschlagen. Sein Beitrag enthält Ansätze zu a) Exportieren einer FSM in JSON (Machine -> JSON), b) Erzeugen von Python FSM-Code aus JSON und c) Einspritzen einer FSM in eine Klasse aus JSON. All dies sollte leicht auf YAML übertragbar sein.

Verwandte Themen