This is python package that offer state machine solution by class decorator.
install
pip3 install statemachine-decorator
example
from statemachine_decorator import statemachine
@statemachine.stateDefine({
"solid": {"gas", "fuild"},
"fuild": {'solid', "gas"},
"gas": {"solid", "fuild", "ionization"},
"ionization": {"gas"}
})
class matter:
def __init__(self):
self.switch("solid")
mat = matter()
print(mat.state)
more detail
from src.statemachine_decorator import stateDefine
if __name__ == '__main__':
# States data structure is a net, main class is StateNet, it countains node class called StateNode.
# Every state is a string, the state node is s subclass of str
# A stateful class could be created like this:
@stateDefine({
"state1": set(), # refers to no entry, means no state can switch "state1",
"state2": {"state1", "state3"},
# refers to two entry, that means the object can switch to "state2" when its state is "state1" or "state3"
"state3": {"state2", "state3"}, # refers to two entry, one is the state itself
# it will raises an error if any string in args[0].values() (refers to above three python sets) is not exsits in the args[0].keys()(refers to the three string)
# it will alse raise an error if you pass a non-str state key to the dict
})
class StatefulItem:
# any class be decorated will be added attributes and a method below:
# method:
# switch(self, new_state: str):
# # switch to a new state
# # if the new state is not switchable (i.e. "state2" switch to "state1" or "state2" switch to "any other state that not exists"), it will raise an error
# attributes:
# state:
# # readonly property
# # type: str
# # probably value are states you passed in stateDefine function above: "state1" | "state2" | "state3"
# # can noly be changed by switch method.
def __init__(self, state: str):
self.switch(state)
class subItem(StatefulItem):
# inherit father's states
def __init__(self):
self.switch("state3")
@stateDefine({
'state1': {'state2'},
# modify father's states. It cause to father's 'state1' has the new one entry, and if father's 'state1' has old entrys, they will be cut totally.
"state2": {"state1"},
# this modify will cut old entries: "state1" -> "state2", "state3" -> "state2", and build new : "state4" -> "state2"
"state4": {"state1", "state3"} # add new state! And relate it to old states.
# ATTENTION: sub class can only add new state and modify old state's entries, if you want to delete old state, please change a mind(reconstruct your class relationships)
})
# new in 1.1.0
class subItem2(StatefulItem):
pass
@stateDefine({}, "state3")
# default state, which will trigger a switch() function call after __init__ is called
class subitem3(StatefulItem):
pass
@stateDefine({}, "state2")
# rewrite default state, ATTENTION: it is unsafe, because super class will call switch previously,
# and that place the object to the super class's default state, and then may cause an impossible switching.
class subsubitem3(subitem3):
pass
item = StatefulItem("state1")
print(item.state) # "state1"
item.switch("state2")
print(item.state) # "state2"
# item.switch('state1') # will raise an error because "state1" has no entry, don't even say "state2"
try:
item.switch("state1")
print("never")
except ValueError:
print("cannot switch to state1!")
print(item.state1, item.state2, item.state3)
subitem = subItem()
print(subitem.state)
subitem.switch('state2')
print(subitem.state)
for s in subitem.states:
print(s, s.nextStates)
subitem = subItem2('state2')
print(subitem.state)
subitem.switch('state1')
print(subitem.state)
subitem.switch('state4')
print(subitem.state)
for s in subitem.states:
print(s, s.nextStates)
subi3 = subitem3()
print(subi3.state)
subi4 = subsubitem3()
print(subi4.state)
more document see:__ init__.py
New in 1.2.5
NS as a new special value of the none state is added! You can pass None or NS to the first parameter to use it!
The NS state is a special state, which represent that the object has no current state, which is also a special state.
Release files for statemachine-decorator 2.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| statemachine_decorator-2.0.2.tar.gz | 9.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| statemachine_decorator-2.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.3 kB
Release files / statemachine_decorator-2.0.2.tar.gz
| Download URL | statemachine_decorator-2.0.2.tar.gz |
|---|---|
| Size | 9.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f7f17320ddff0b67c2d32b93006995547216f1c6e89d34807fbdab34747881a1
|
|
BLAKE2b-256 checksum How to use checksums |
3e3c1a8d3271b28837d50ab640d13a620ac2bc272f0c8766de3ad732489af693
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.7
|
Release files / statemachine_decorator-2.0.2-py3-none-any.whl
| Download URL | statemachine_decorator-2.0.2-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6db28c5aa10655d50e934c4ef6da25c1d98ba72cd6bb925665d26e4dfb756cd1
|
|
BLAKE2b-256 checksum How to use checksums |
cdc94e714ca0142f1b35d6c425533cdf2c6fcc84588a4feb9234ef67ba9a37f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.7
|