- Oluliste dunder-meetodite (nt __init__, __repr__ ja __eq__) automaatne genereerimine standardsete meetodite vähendamiseks.
- Objektide käitumise täiustatud kontroll parameetrite abil, näiteks muutmatuse tagamiseks külmutamine ja sortimise järjekord.
- Üksikute väljade kohandamine funktsiooni field() ja post-institatsiooni loogika abil __post_init__ abil.
- Sujuv integratsioon tüübivihjete ja klasside pärimise toega keerukate andmehierarhiate loomiseks.
Kas oled kunagi tundnud, et kulutad rohkem aega korduvate konstruktorimeetodite kirjutamisele kui oma projekti loogika kodeerimisele? Kui oled kunagi ehitanud klassi ainult hulga väärtuste hoidmiseks, siis tead, kui keeruline on iga üksiku argumendi käsitsi self.attribute'ile kaardistamine . See on tüütu, altid trükivigadele ja ausalt öeldes natuke tüütu igale arendajale, kes püüab oma koodibaasi puhtana hoida.
Tutvustame Pythoni andmeklassid , mängumuutjat, mis tutvustati versioonis 3.7 andmeklasside mooduli kaudu . Need ei ole täiesti uut tüüpi klassid, vaid pigem nutikas viis dekoraatori kasutamiseks objektorienteeritud programmeerimise igavate osade automatiseerimiseks. PEP 557 ja PEP 526 abil võimaldavad need teil määratleda oma andmete struktuuri tüübimärkuste abil, lastes Pythonil hakkama saada alusmehhanismide genereerimise raske tööga.
@dataclass Decoratori võlujõud

Oma põhiolemuses skannib @dataclass dekoraator teie klassi definitsiooni, et leida muutujaid, millel on tüübivihjed. Kui see need leiab, lisab see teie klassi automaatselt mitu „dunder” (topelt alakriipsu) meetodit . Kõige vahetum kasu on meetod __init__() , mis tähendab, et saate oma objekti luua ilma ühtegi rida omistamisloogikat kirjutamata. Kuid see pole veel kõik; saate ka meetodi __repr__() , mis pakub teie objektist puhta ja loetava stringesituse, muutes silumise imelihtsaks võrreldes krüptiliste mäluaadressidega, mida tavalised klassid pakuvad.
Lisaks põhitõdedele pakub dekoraator ka võrduskontrollid funktsiooni __eq__() abilStandardklassis kahe samade andmetega objekti võrdlemine, kasutades == tagastaks väärtuse „väär”, kuna Python kontrollib, kas need on mälus sama eksemplar. Andmeklassid muudavad seda järgmiselt: tegelike väärtuste võrdlemine väljadest, käsitledes objekti nagu selle andmete paari. Saate isegi lubada sorteerimisvõimalused seadistades järjekord=Tõsi, mis genereerib meetodeid nagu __lt__ ja __gt__, mis võimaldab teil objektide loendeid nende atribuutide alusel sortida.
Käitumise peenhäälestamine parameetrite abil
@dataclass dekoraator on väga seadistatav. Näiteks kui soovite jäljendada kirjutuskaitstud objekte, saate määrata külmutatud=tõsiSee hoiab ära atribuudi muutmise pärast objekti loomist, visates välja vea. Külmutatud eksemplari viga kui keegi proovib väärtust muuta. Kuigi see lisab eksemplari loomisel väikese jõudluslanguse, on see suurepärane viis tagada andmete terviklikkus kogu teie rakenduses. Kui olete mures mälu või kiiruse pärast, siis seadistage pesad=Tõsi saab muuta teie klassid lihtsamaks ja kiiremaks, takistades vaikimisi loomise loomist __dict__.
Teiste käepäraste parameetrite hulka kuulub kw_only=True , mis sunnib kõik konstruktori argumendid edastama märksõnaargumentidena, vähendades väärtuste vales järjekorras edastamise riski. Samuti on olemas match_args , mis aitab klassil Pythoni struktuurimustrite sobitamisega sujuvalt töötada. Kui leiate, et te ei vaja konkreetset meetodit, näiteks konstruktorit või esitusstringi, saate lihtsalt määrata init=False või repr=False, et öelda Pythonile need vahele jätta.
Sügav sukeldumine funktsiooni field() olemusse
Mõnikord ei piisa lihtsast tüübimärkusest. Siin ongi koht, kus välja() funktsioon tuleb mängu. See võimaldab teil iga atribuudi jaoks anda detailseid juhiseid. Näiteks kui teil on väli, mis ei peaks olema osa __init__ meetod aga peaks objektil ikkagi olemas olema, saate määrata init=FalseSamamoodi saate tundlikke andmeid peita __repr__ väljund seadistades repr=False.
Üks olulisemaid kasutusviise field() tegeleb muudetavad vaikeväärtusedPythonis on loendi või sõnastiku kasutamine vaike-argumendina katastroofi retsept, kuna vaikeväärtust jagatakse kõigi eksemplaride vahel. Selle parandamiseks kasutate vaiketehasKutsutava (näiteks list or dict), Python tagab, et muudetava objekti uus eksemplar luuakse iga kord, kui uus andmeklass luuakse, vältides kardetud jagatud oleku viga.
Täiustatud loogika ja pärimine
Kui teil on vaja arvutusi või valideerimist teha kohe pärast objekti loomist, siis __post_init__() meetod on su parim sõber. Kuna @dataclass genereeriti __init__ tegeleb põhiliste ülesannetega, __post_init__ võimaldab teil tuletada uusi väärtusi olemasolevatest väljadest. Seda kasutatakse sageli koos InitVar, mis defineerib konstruktorile edastatavad muutujad ja __post_init__ kuid neid ei salvestata eksemplari tegelike atribuutidena.
Pärimine töötab andmeklassidega intuitiivselt, kuid vaikeväärtustega on üks konks . Andmeklassist pärimisel ühendab Python põhiklassi ja tuletatud klassi väljad järjekorras. Tulenevalt sellest, kuidas Python funktsioonide argumente käsitleb, ei saa vaikeväärtusega väljale järgneda välja, millel seda pole . Seega, kui teie põhiklassil on atribuute vaikeväärtustega, peab ka igal alamklassi atribuudil olema vaikeväärtus, et vältida tüübivea (TypeError).
Andmekonteinerid vs. käitumuslikud klassid
Oluline on meeles pidada, et andmeklassid on eelkõige oleku, mitte käitumise konteinerid . Kuigi neile saab lisada meetodeid, võib keeruka, olekut muutva loogika lisamine arhitektuurilist eesmärki hägustada. Kui teie klassist on saamas keeruline üksus, millel on palju meetodeid, mis muudavad selle sisemist olekut, võib olla aeg naasta standardsele OO-klassile . Andmeklassid on kõige eredamad domeeni modelleerimiseks , teabe edastamiseks süsteemikihtide vahel või lihtsate API-vastuste loomiseks.
Töövoo edasiseks sujuvamaks muutmiseks pakub moodul utiliidifunktsioone nagu asdict() ja astuple() , mis teisendavad pesastatud andmeklassid rekursiivselt standardseteks Pythoni sõnaraamatuteks või tuple'ideks. Samuti on olemas replace() , mis loob objektist pealiskaudse koopia, võimaldades samal ajal teatud välju muuta, muutes selle ideaalseks töötamiseks külmutatud eksemplaridega, kus otsene muteerimine on keelatud.
Konstruktorite, esituste ja võrduskontrollide malli automatiseerimise abil saavad need tööriistad arendajatel keskenduda tegelikule andmestruktuurile, mitte klassi loomise mehaanikale. Olenemata sellest, kas ehitate lihtsat konstantide kogumit või keerukat pesastatud andmehierarhiat, tagab nende dekoraatorite kasutamine, et teie kood jääb kokkuvõtlikuks, loetavaks ja hooldatavaks, kasutades samal ajal ära Pythoni tüübisüsteemi täielikku võimsust.