Dátové triedy
ako na dátové triedy s modulom udataclasses
Dátové triedy sú špeciálne triedy, ktoré slúžia na prenos dát. Obsahujú obyčajne iba členské premenné a minimum logiky. Často sa používajú na manažment konfigurácie alebo na správu serializovateľných údajov, ktoré sa napr. prenášajú prostredníctvom REST API alebo protokolom MQTT. Štandardná knižnica jazyka Python obsahuje priamu podporu v balíku dataclasses, ale najznámejšou knižnicou je rozhodne Pydantic.
Natívna podpora dátových tried v jazyku MicroPython však nie je a rovnako
vlastnosti tohto jazyka obmedzujú ich plnohodnotné využívanie. Pre naše
potreby budeme používať jednoduchú implementáciu v podobe modulu
udataclasses.py, ktorý je inšpirovaný práve knižnicou Pydantic. Jej kód je
súčasťou šablóny THSensor
Vlastnosti modulu
udataclasses.py
- typová kontrola pri priradení hodnoty
- typ určuje prvá priradená hodnota
- pri ďalšom priradení sa kontroluje, či nová hodnota zodpovedá typu prvej priradenej hodnoty
- slot-like správanie - nie je možné pridávať nové tribúty, ktoré nie sú definované v triede
- dekorátor
validatorna tvorbu vlastných funkcií na validáciu členských premenných- validácia sa spustí automaticky pri pri priradení novej hodnoty
- vytvorená trieda je iterovateľná
- export dát do slovníka pomocou volania metódy
.model_dump()- exportujú sa aj vnorené dátové triedy
- reprezentácia objektu pomotou
__repr__()- objekt sa vypíše v tvare
ClassName(field=value, ...)
- objekt sa vypíše v tvare
Vytvorenie triedy
class Address(Dataclass):
city: str = None
zip: str = None
class Person(Dataclass):
name: str = None
age: int = None
address: Address = NoneVytvorenie inštancie
Inštanciu je možné vytvoriť priamo pomocou konštruktora:
p = Person(
name="Alice",
age=30,
address=Address(city="Paris", zip='12345')
)Rovnako je ju však možné vytvoriť rozbalením slovníka:
>>> d = {
'address': {
'zip': '54321',
'city': 'Kosice'
},
'age': 23,
'name': 'Juraj'
}
>>> p2 = Person(**d)
>>> print(p2)
Person(age=23,name='Juraj',address={'zip': 54321, 'city': 'Kosice'})Čítanie hodnôt
>>> print(f'{p.name} is {p.age} years old and lives in {p.address.city}.')
Alice is 30 years old and lives in Paris.Zápis hodnôt
Pri zápise hodnôt je dôležité, aby typ zapisovanej hodnoty zodpovedal
typu členskej premennej. V opačnom prípade dôjde k výnimke
ValueError:
# typ clenskej premennej p.age je int
>>> type(p.age)
<class 'int'>
# ak priradime hodnotu typu int, je vsetko v poriadku
>>> p.age = 32
# ak vsak priradime hodnotu ineho typu, dojde k vynimke
>>> p.age = 'twenty'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "models/udataclasses.py", line 67, in __setattr__
ValueError: Value "twenty" for attribute "age" is not of type "int".Ak je však členská premenná po vytvorení typu None, jej
typ sa určí pri priradení prvej hodnoty, ktorá nebude
None:
>>> p3 = Person()
>>> p3.name = 'jano'
>>> p3.name = 23
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "models/udataclasses.py", line 67, in __setattr__
ValueError: Value "23" for attribute "name" is not of type "str".Validácia hodnôt
V triede, ktorá je potomkom triedy Dataclass je možné
vytvárať aj vlastné validátory členských premenných. Stačí vytvoriť
inštančnú metódu s dekorátorom @validator():
class Person(Dataclass):
name: str = None
age: int = None
address: Address = None
@validator('age')
def check_age(self, value):
if value < 0:
raise ValueError('Age is negative')