[PYTHON] Implementieren Sie ein Modell mit Status und Verhalten

Betrachten Sie Schalter (Einschaltknopf für Beleuchtung, Zielknopf auf jeder Etage des Aufzugs usw.) als primitives Modell mit Status und Verhalten. Der Schalter hat zwei Zustände, einen gedrückten Zustand "Ein" und einen nicht gedrückten Zustand "Aus". Auch das Verhalten des Schalters "switch ()" ändert sich je nach Status. Wenn es gedrückt wird, befindet es sich im nicht gedrückten Zustand "Aus", und wenn es nicht gedrückt wird, befindet es sich im gedrückten Zustand "Ein".

example1


class Switch:
    def __init__(self, state="off"):
        self.state = state

    def switch(self):
        if self.state == "on":
            self.state = "off"
        elif self.state == "off":
            self.state = "on"
        else:
            # I wonder whether it should be ValueError().
            raise RuntimeError(self.__class__.__name__ + " has an unexpected state: {}".format(self.state))


switch = Switch()
assert switch.state == "off"
switch.switch()
assert switch.state == "on"
switch.switch()
assert switch.state == "off"
switch.state = True
switch.switch()
-> RuntimeError: Switch has an unexpected state: True

Für die möglichen Werte (Zustände) von "Switch.state" müssen Sie sich die Implementierung von "Switch" ansehen. Die Verwendung von Aufzählungswerten zur Darstellung von Zuständen kann beispielsweise die Sichtbarkeit verbessern.

example2


from enum import Enum, auto


class SwitchState(Enum):
    ON = auto()
    OFF = auto()


class Switch:
    def __init__(self, state=SwitchState.OFF):
        self.state = state

    def switch(self):
        if self.state == SwitchState.ON:
            self.state = SwitchState.OFF
        elif self.state == SwitchState.OFF:
            self.state = SwitchState.ON
        else:
            raise RuntimeError(self.__class__.__name__ + " has an unexpected state: {}".format(self.state))


switch = Switch(SwitchState.ON)
switch.switch()
switch = Switch("on")  # warning: expected SwitchState type

Wenn der Standardwert des Konstruktorarguments "state" auf "SwitchState" gesetzt ist, wird eine Warnung für andere Werte als "SwitchState" ausgegeben. Unerwartete Werte wie "Ein" können jedoch "Switch.state" wie folgt zugewiesen werden.

switch.state = True
switch.switch()  # RuntimeError: Switch has an unexpected state: True

Sie bemerken nicht, dass ein unerwarteter Wert zugewiesen wurde, bis switch () aufgerufen wurde. Daher ist es einfacher, einen TypeError zu senden, wenn "Switch.state" wie unten gezeigt ein unerwarteter Wert zugewiesen wird.

example2


class Switch:
    def __init__(self, state=SwitchState.OFF):
        self._state = state

    def switch(self):
        if self._state == SwitchState.ON:
            self._state = SwitchState.OFF
        elif self._state == SwitchState.OFF:
            self._state = SwitchState.ON
        else:
            raise RuntimeError(self.__class__.__name__ + " has an unexpected state: {}".format(self._state))

    @property
    def state(self) -> SwitchState:
        return self._state

    @state.setter
    def state(self, value: SwitchState):
        if type(value) is not SwitchState:
            raise TypeError(self.__class__.__name__ + ".state must be SwitchState, but get: {}".format(type(value)))
        self._state = value


switch = Switch(SwitchState.ON)
switch.switch()
switch.state = True  # TypeError: Switch.state must be SwitchState, but get: <class 'bool'>

Wenn Sie nicht möchten, dass der Status von "Switch" von außerhalb der Klasse geändert wird, können Sie in "Switch.state" keinen Wert festlegen.

class Switch:
    def __init__(self, state=SwitchState.OFF):
        self._state = state

    def switch(self):
        if self._state == SwitchState.ON:
            self._state = SwitchState.OFF
        elif self._state == SwitchState.OFF:
            self._state = SwitchState.ON
        else:
            raise RuntimeError(self.__class__.__name__ + " has an unexpected state: {}".format(self._state))

    @property
    def state(self) -> SwitchState:
        return self._state


switch = Switch(SwitchState.ON)
switch.switch()
switch.state = SwitchState.OFF  # Property cannot be set

Wenn Sie den Status von "Switch" von außerhalb der Klasse ändern möchten, ist es besser, die Methoden "turn_on ()", "turn_off ()" für den Statusübergang bereitzustellen, als "Switch.state" an außerhalb der Klasse abzugeben. In manchen Fällen.

class Switch:
    def __init__(self, state=SwitchState.OFF):
        self._state = state

    def switch(self):
        if self._state == SwitchState.ON:
            self.turn_off()
        elif self._state == SwitchState.OFF:
            self.turn_on()
        else:
            raise RuntimeError(self.__class__.__name__ + " has an unexpected state: {}".format(self._state))

    @property
    def state(self) -> SwitchState:
        return self._state

    def turn_on(self):
        self._state = SwitchState.ON
    
    def turn_off(self):
        self._state = SwitchState.OFF


switch = Switch()
switch.turn_off()
assert switch.state == SwitchState.OFF
switch.switch()
assert switch.state == SwitchState.ON

Schließlich werden wir die Implementierung basierend auf dem Hinzufügen von Funktionen zu "Switch" später ändern. Bisher wurde es so implementiert, dass sich das Verhalten je nach Status ändert (die Verarbeitung der Methode unterscheidet sich je nach Status), es kann jedoch auch so implementiert werden, dass der Status durch den Unterschied im Verhalten ausgedrückt wird (der Status unterscheidet sich je nach Unterschied in der Verarbeitung). es kann.

from enum import Enum, auto


class SwitchState(Enum):
    ON = auto()
    OFF = auto()


class Switch:
    def __init__(self, state=SwitchState.OFF):
        self.switch = self.turn_on if state == SwitchState.OFF else self.turn_off

    @property
    def state(self) -> SwitchState:
        return SwitchState.OFF if self.switch == self.turn_on else SwitchState.ON

    def turn_on(self):
        self.switch = self.turn_off

    def turn_off(self):
        self.switch = self.turn_on


switch = Switch(SwitchState.ON)
switch.switch()
assert switch.state == SwitchState.OFF
switch.switch()
assert switch.state == SwitchState.ON

Es gibt keinen Unterschied in der Funktionalität von "Switch", nur die Implementierung ist unterschiedlich.

Recommended Posts

Implementieren Sie ein Modell mit Status und Verhalten
Implementieren Sie ein Modell mit Status und Verhalten (3) - Beispiel für die Implementierung durch den Dekorateur
Implementieren Sie mit stan ein zeitdiskretes logistisches Regressionsmodell
Erstellen Sie mit PyQt5 und PyQtGraph einen 3D-Modell-Viewer
Erstellen Sie mit PySide einen Modelliterator
Ein Memo mit Python2.7 und Python3 in CentOS
Implementieren Sie ein benutzerdefiniertes Benutzermodell in Django
Probieren Sie TensorFlows RNN mit einem Basismodell aus
Erstellen Sie einen Stapel mit einer Warteschlange und eine Warteschlange mit einem Stapel (von LetCode / Implement Stack using Queues, Implement Queue using Stacks)
Todo-App mit Django erstellen ④ Ordner- und Aufgabenerstellungsfunktion implementieren
Ein Modell, das die Gitarre mit fast.ai identifiziert
Verbinden Sie Scratch X und Digispark mit der Flasche
Laden Sie das Kaffeemodell mit Chainer und klassifizieren Sie die Bilder
Erstellen einer Python-Umgebung mit virtualenv und direnv
Vorhersage des heißen Sommers mit linearem Regressionsmodell
Verwalten Sie Statusübergänge und kommunizieren Sie mit intelligenten Zählern
Erstellen Sie eine virtuelle Umgebung mit pyenv und venv
Starten Sie einen Webserver mit Python und Flask
Kompilieren Sie Rust und führen Sie es mit einem einzigen Befehl aus
Lösen des Lorenz 96-Modells mit Julia und Python
Ich habe versucht, "Grundlagen der Zeitreihenanalyse und des Zustandsraummodells" (Hayamoto) mit Pystan zu implementieren
Erstellen Sie mit Azure Custom Vision explosionsartig ein Bildklassifizierungsmodell und implementieren Sie es mit Flask
Versuchen Sie, eine einfache Website mit Responder und sqlite3 zu erstellen
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Erstellen Sie eine virtuelle Python-Umgebung mit virtualenv und virtualenvwrapper
Erstellen Sie mit Py2app und Tkinter eine native GUI-App
[# 2] Mach Minecraft mit Python. ~ Modellzeichnung und Player-Implementierung ~
Erstellen Sie einen Stapel von Bildern und blasen Sie sie mit ImageDataGenerator auf
Ich habe versucht, LINE BOT mit Python und Heroku zu machen
Erstellen Sie eine virtuelle Python-Umgebung mit virtualenv und virtualenvwrapper
Lassen Sie uns eine Mac-App mit Tkinter und py2app erstellen
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
Implementieren Sie ein Modell mit Status und Verhalten (3) - Beispiel für die Implementierung durch den Dekorateur
Beispiel für die Verwendung von Klassenvariablen und Klassenmethoden
Lernen Sie Wasserstein GAN mit Keras-Modell und TensorFlow-Optimierung
Sehen Sie sich das Profiling und Dumping mit Dataflow an
[Linux] Erstellen Sie ein Selbstzertifikat mit Docker und Apache
Erstellen einer numerischen Berechnungsumgebung mit pyenv und miniconda3
Implementieren Sie FReLU mit tf.keras
A4 Größe mit Python-Pptx
Modellkomplexität und Robustheit
Modellbefestigung mit lmfit
Regression mit einem linearen Modell
Mit Dekorateur dekorieren
[In-Database Python Analysis Tutorial mit SQL Server 2017] Schritt 5: Training und Speichern von Modellen mit T-SQL
Mit und ohne WSGI
Implementieren Sie mit OpenModelica das mathematische Modell "SIR-Modell" von Infektionskrankheiten (Beispiel für wiederholte Regulierung und Entspannung)
Ich habe versucht, das grundlegende Modell des wiederkehrenden neuronalen Netzwerks zu implementieren
Speichern Sie das Pystan-Modell und erhalten Sie eine Pickle-Datei
Konvertieren Sie RGB und HSV mit PyTorch in teilbare Form
[Django] Verwalten Sie Einstellungen wie das Schreiben in settings.py mit einem Modell
Ein einfacher interaktiver Musikplayer mit Chuck und OpenPose
Als Ergebnis der Montage und Abstimmung mit POH! Lite
Erstellen Sie eine WEB-Überwachungskamera mit Raspberry Pi und OpenCV
Implementieren Sie mit Open Modelica das mathematische Modell "SIR-Modell" von Infektionskrankheiten
Verknüpfen Sie Python Enum mit einer Funktion, um es aufrufbar zu machen
[Azure] Erstellen, Bereitstellen und erneutes Lernen eines Modells [ML Studio classic]
Verhalten beim Angeben einer Liste mit shell = True im Unterprozess
Erstellen Sie Anwendungen, registrieren Sie Daten und teilen Sie sie mit einer einzigen E-Mail
Lassen Sie uns ein PRML-Diagramm mit Python, Numpy und matplotlib erstellen.