[PYTHON] Implémenter un modèle avec état et comportement (3) - Exemple d'implémentation par décorateur

La dernière fois (Implémenter un modèle avec des états et des comportements (2)), nous avons implémenté StopWatch avec trois états de deux manières. .. Cette fois, StopWatch est implémenté en utilisant * decorator *.

Tout d'abord, décrivez la transition d'état avec * decorator *. Il sera plus facile de comprendre s'il s'agit d'une méthode de transition d'état.

from enum import auto


def transit(state):
    def decorator(func):
        def inner(self, *args, **kwargs):
            self.start_stop, self.reset = self._TRANSIT[state]
            func(self, *args, **kwargs)
        return inner
    return decorator


class StopWatch:
    WAIT, PAUSE, MEASURE = auto(), auto(), auto()

    def __init__(self):
        self._TRANSIT = {StopWatch.WAIT: (self.start, lambda *args: None),
                         StopWatch.PAUSE: (self.start, self.reset_time),
                         StopWatch.MEASURE: (self.pause, lambda *args: None)}
        self._TRANSIT_REVERSED = {v: k for k, v in self._TRANSIT.items()}
        self.start_stop, self.reset = self._TRANSIT[StopWatch.WAIT]

    @property
    def state(self):
        return self._TRANSIT_REVERSED[self.start_stop, self.reset]

    @transit(MEASURE)
    def start(self):
        pass

    @transit(PAUSE)
    def pause(self):
        pass

    @transit(WAIT)
    def reset_time(self):
        pass

De plus, essayez de découper la table de transition d'état avec un décorateur. Le décorateur behavior représente le comportement dans un certain état.

from enum import auto
from state_machine import behavior, transit


class StopWatch:
    WAIT, MEASURE, PAUSE = auto(), auto(), auto()

    def __init__(self):
        self.state = StopWatch.WAIT

    @behavior(WAIT, "start")
    @behavior(MEASURE, "pause")
    @behavior(PAUSE, "start")
    def start_stop(self):
        pass

    @behavior(PAUSE, "reset_time")
    def reset(self):
        pass

    @transit(MEASURE)
    def start(self):
        pass

    @transit(PAUSE)
    def pause(self):
        pass

    @transit(WAIT)
    def reset_time(self):
        pass

state_machine.py


from functools import wraps


def transit(state):
    def decorator(func):
        @wraps(func)
        def inner(self, *args, **kwargs):
            self.state = state
            func(self, *args, **kwargs)
        return inner
    return decorator


def behavior(state, function):
    def decorator(func):
        @wraps(func)
        def inner(self, *args, **kwargs):
            if self.state == state:
                getattr(self, function)(*args, **kwargs)
            else:
                func(self, *args, **kwargs)
        return inner
    return decorator

Bien que l'on suppose que l'état est conservé dans self.state, le même * décorateur * peut être utilisé dans d'autres modèles, il a donc été découpé en tant que module state_machine.

Au moment du traitement du décorateur, la fonction n'est toujours pas liée, le comportement est donc donné sous forme de chaîne de caractères. Vous pouvez également utiliser la fonction «name» pour appeler une méthode liée à l'exécution. (Seules les pièces applicables sont illustrées ci-dessous.) Notez que s'il y a un * décorateur * qui n'utilise pas functools.wrap (), il ne fonctionnera pas comme prévu. (* Decorator * ne réécrit pas la fonction __name__ lors de l'utilisation de functools.wrap ().)

state_machine.py


def behavior(state, function):
...
            if self.state == state:
                getattr(self, function.__name__)(*args, **kwargs)
...
...
    @behavior(PAUSE, reset_time)
    def reset(self):
        pass
...

Recommended Posts

Implémenter un modèle avec état et comportement (3) - Exemple d'implémentation par décorateur
Implémenter un modèle avec état et comportement
Implémenter le modèle mathématique «modèle SIR» des maladies infectieuses avec OpenModelica (exemple de régulation répétée et de relaxation)
Faisons une application qui affaiblit les nerfs avec Vue.js et Django-Rest-Framework [Partie 3] ~ Implémentation de la faiblesse nerveuse ~
Fonction de transmission / modèle d'espace d'état du circuit série RLC et simulation par Python
Implémentation de l'arbre TRIE avec Python et LOUDS
Mise en place d'un modèle de prédiction des taux de change (taux dollar-yen) par machine learning
Implémenter un modèle de régression logistique en temps discret avec stan
Exemple de lecture et d'écriture de CSV avec Python
Fonction de transmission / modèle d'espace d'état du système ressort / masse / amortisseur et simulation par Python
J'ai essayé d'implémenter "Bases de l'analyse des séries temporelles et du modèle d'espace d'état" (Hayamoto) avec pystan
[Python] Implémentation du clustering à l'aide d'un modèle gaussien mixte
[# 2] Créez Minecraft avec Python. ~ Dessin du modèle et implémentation du lecteur ~
Créez un lot d'images et gonflez avec ImageDataGenerator
Créer une visionneuse de modèle 3D avec PyQt5 et PyQtGraph
Création, apprentissage et raisonnement de modèles d'apprentissage
Mémorandum de sauvegarde et modèle de chargement
Modèle de régression utilisant scikit-learn et sa visualisation
Chargement et test du modèle imagenet entraîné de Chainer
Implémenter un modèle avec état et comportement
Décorer avec un décorateur
Une histoire de lecture d'un livre d'images en synthétisant la voix avec l'API COTOHA et l'API Cloud Vision
Exemple de mise en œuvre de la gestion centralisée de l'inventaire et des variables en liant Ansible et serverspec (prend en charge plusieurs serveurs)
Implémentation de VGG16 à l'aide de Keras créé sans utiliser de modèle entraîné
Sauvegardez la sortie de GAN une par une ~ Avec l'implémentation de GAN par PyTorch ~
Implémenter le modèle mathématique «modèle SIR» des maladies infectieuses avec Open Modelica
Détecter les objets d'une couleur et d'une taille spécifiques avec Python
Analysez le modèle thématique pour devenir romancier avec GensimPy3
Explication du CSV et exemple d'implémentation dans chaque langage de programmation
Analyse de séries temporelles par modèle général d'espace d'états gaussien à l'aide de Python [Exemple d'implémentation considérant extrinsèque et saisonnalité]
Une histoire et sa mise en œuvre selon laquelle des données arbitraires a1 * a2 peuvent être représentées par un réseau de neurones ReLU à 3 couches avec des neurones intermédiaires a1 et a2 sans erreur.
Explication et mise en œuvre de SocialFoceModel
Créez facilement un profil avec un décorateur
Construction d'environnement de Tensorflow et Chainer par Window avec CUDA (avec GPU)
L'exemple de Miyashita de la mécanique analytique, des exercices résolus et déplacés avec l'animation
Exploration avec Python et Twitter API 2-Implémentation de la fonction de recherche d'utilisateurs
[Objet obligatoire DI] Implémenter et comprendre le mécanisme de DI avec Go
[Python] Implémentation de la méthode Nelder – Mead et sauvegarde des images GIF par matplotlib
Essayez de faire une stratégie de blackjack en renforçant l'apprentissage ((1) Implémentation du blackjack)
Exemple d'implémentation d'un réseau de génération hostile (GAN) par Keras
Définissez un type d'argument personnalisé avec un clic (Exemple: Implémentation d'un type qui fait d'une chaîne eval une valeur optionnelle)
Construction d'un environnement distribué avec la série Raspberry PI (Partie 1: Résumé de la disponibilité des clients sans disque par modèle)