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.
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
validator
na 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):
str = None
city: zip: str = None
class Person(Dataclass):
str = None
name: int = None
age: = None address: Address
Vytvorenie inštancie
Inštanciu je možné vytvoriť priamo pomocou konštruktora:
= Person(
p ="Alice",
name=30,
age=Address(city="Paris", zip='12345')
address )
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)
=23,name='Juraj',address={'zip': 54321, 'city': 'Kosice'}) Person(age
Čítanie hodnôt
>>> print(f'{p.name} is {p.age} years old and lives in {p.address.city}.')
is 30 years old and lives in Paris. Alice
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):"<stdin>", line 1, in <module>
File "models/udataclasses.py", line 67, in __setattr__
File 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):"<stdin>", line 1, in <module>
File "models/udataclasses.py", line 67, in __setattr__
File 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):
str = None
name: int = None
age: = None
address: Address
@validator('age')
def check_age(self, value):
if value < 0:
raise ValueError('Age is negative')