Všetko v Pythone je objekt, alebo sa tak aspoň hovorí. Ak chcete vytvoriť svoje vlastné vlastné objekty s vlastnými vlastnosťami a metódami, použijete Python’s trieda
objekt, aby sa tak stalo. Ale vytváranie tried v Pythone niekedy znamená písanie množstva opakujúcich sa kódov štandardných kódov na nastavenie inštancie triedy z parametrov, ktoré sa jej odovzdávajú, alebo na vytvorenie bežných funkcií, ako sú operátory porovnania.
Datové triedy, zavedené v Pythone 3.7 (a spätne podporované v Pythone 3.6), poskytujú praktický spôsob, ako triedy menej verbovať. Mnoho bežných vecí, ktoré v triede robíte, napríklad vytváranie inštancií vlastností z argumentov odovzdaných triede, je možné obmedziť na niekoľko základných pokynov.
Príklad dátovej triedy Python
Tu je jednoduchý príklad konvenčnej triedy v Pythone:
triedna kniha:'' 'Objekt na sledovanie fyzických kníh v zbierke.' ''
def __init __ (self, name: str, weight: float, shelf_id: int = 0):
self.name = meno
self.weight = hmotnosť # v gramoch, na výpočet poštovného
self.shelf_id = police_id
def __repr __ (self):
návrat (f "Kniha (meno = {self.name! r}),
weight = {self.weight! r}, shelf_id = {self.shelf_id! r}) ")
Najväčšou bolesťou hlavy je spôsob, akým sa odovzdávajú všetky argumenty__init__
musí byť skopírovaný do vlastností objektu. To nie je také zlé, ak máte do činenia iba sKniha
, ale čo ak sa s tým musíte vyrovnaťPolička
, Knižnica
, Sklad
, a tak ďalej? Čím viac kódu budete musieť napísať ručne, tým väčšia je pravdepodobnosť, že urobíte chybu.
Tu je rovnaká trieda Python implementovaná ako dátová trieda Python:
from dataclasses import dataclass @dataclass class Kniha: '' 'Objekt na sledovanie fyzických kníh v zbierke.' '' name: str weight: float shelf_id: int = 0
Keď zadáte vlastnosti, tzvpolia, v datovej triede,@dataclass
automaticky generuje všetok kód potrebný na ich inicializáciu. Zachováva tiež informácie o type pre každú vlastnosť, takže ak používate kódový linter akomypy
, zabezpečí to, že budete dodávať správne druhy premenných do konštruktora triedy.
Ďalšia vec@dataclass
robí v zákulisí je automaticky vytvoriť kód pre rad bežných metód dunder v triede. V konvenčnej triede vyššie sme si museli vytvoriť vlastnú__repr__
. V dátovej triede je to zbytočné;@dataclass
generuje__repr__
pre teba.
Po vytvorení dátovej triedy je funkčne identická s bežnou triedou. Za použitie dátovej triedy neplatí žiadny výkonnostný trest, s výnimkou minimálnej réžie dekoratéra pri deklarácii definície triedy.
Prispôsobte si polia dátovej triedy Pythonu pomocoulúka
funkcia
Predvolený spôsob fungovania dátových tried by mal byť pre väčšinu prípadov použitia v poriadku. Niekedy však musíte doladiť spôsob inicializácie polí vo vašej dátovej triede. Môžete to urobiť pomocoulúka
funkcia.
z dataclass import dataclass, pole od písania import List @dataclass class Kniha: '' 'Objekt na sledovanie fyzických kníh v zbierke.' '' name: str podmienka: str = pole (porovnaj = False) váha: float = pole (predvolené = 0,0, repr = False) shelf_id: int = 0 kapitol: Zoznam [str] = pole (default_factory = zoznam)
Keď nastavíte predvolenú hodnotu na inštanciulúka
, mení sa nastavenie poľa podľa toho, aké parametre dátelúka
. Toto sú najčastejšie používané možnosti pre lúka
(existujú aj ďalšie):
predvolené
: Nastaví predvolenú hodnotu pre pole. Musíte použiťpredvolené
ak a) používatelúka
ak chcete zmeniť ďalšie parametre poľa, ab) chcete nastaviť predvolenú hodnotu v poli navyše. V tomto prípade použijemepredvolené
nastaviťváha
do0.0
.default_factory
: Poskytuje názov funkcie, ktorá nemá žiadne parametre a ktorá vráti nejaký objekt, ktorý bude slúžiť ako predvolená hodnota pre pole. V takom prípade chcemekapitol
byť prázdny zoznam.repr
: Predvolene (Pravdaže
), určuje, či sa dané pole zobrazuje v automaticky generovanom__repr__
pre datovú triedu. V takom prípade nechceme, aby bola hmotnosť knihy uvedená v__repr__
, takže používamerepr = nepravda
vynechať to.porovnaj
: Predvolene (Pravdaže
), obsahuje pole v metódach porovnania automaticky generovaných pre dátovú triedu. Tu nechcemestav
použiť ako súčasť porovnania pre dve knihy, tak sme nastaviliporovnaj =
Falošné
.
Upozorňujeme, že sme museli upraviť poradie polí tak, aby boli políčka, ktoré neboli predvolené, na prvom mieste.
Použite__post_init__
na kontrolu inicializácie dátovej triedy Pythonu
V tomto okamihu by vás asi zaujímalo: Ak__init__
metóda dátovej triedy sa generuje automaticky, ako získam kontrolu nad procesom init, aby som mohol vykonať jemnejšie zmeny?
Zadajte znak__post_init__
metóda. Ak zahrniete__post_init__
v definícii svojej dátovej triedy môžete poskytnúť pokyny na úpravu polí alebo iných inštančných údajov.
z dataclass import dataclass, pole od písania import List @dataclass class Kniha: '' 'Objekt na sledovanie fyzických kníh v zbierke.' '' name: str weight: float = field (default = 0.0, repr = False) shelf_id: int = field (init = False) kapitoly: Zoznam [str] = pole (default_factory = zoznam) podmienka: str = field (default = "Dobré", porovnanie = False) def __post_init __ (self): ak self.condition == "Vyradené ": self.shelf_id = Žiadne iné: self.shelf_id = 0
V tomto príklade sme vytvorili a__post_init__
spôsob nastavenia police_id
doŽiadne
ak je stav knihy inicializovaný ako„Zahodené“
. Všimnite si, ako používamelúka
inicializovaťpolice_id
a prejsťinit
akoFalošné
dolúka
. To znamenápolice_id
nebude inicializovaný v__init__
.
PoužiteInitVar
na kontrolu inicializácie dátovej triedy Pythonu
Ďalším spôsobom, ako prispôsobiť nastavenie dátovej triedy Pythonu, je použitie súboruInitVar
typu. Takto môžete určiť pole, do ktorého sa odošle__init__
a potom do__post_init__
, ale nebudú uložené v inštancii triedy.
Používaním InitVar
, pri nastavovaní dátovej triedy môžete brať do úvahy parametre, ktoré sa používajú iba počas inicializácie. Príklad:
z dataklasy import dataklasy, pole, InitVar zo zadania importu Zoznam @dataclass trieda Kniha: '' 'Objekt na sledovanie fyzických kníh v zbierke.' '' názov: str podmienka: InitVar [str] = Žiadna váha: float = pole (predvolené) = 0.0, repr = False) shelf_id: int = field (init = False) kapitoly: Zoznam [str] = pole (default_factory = zoznam) def __post_init __ (self, podmienka): ak podmienka == "Vyradené": self.shelf_id = Žiadne iné: self.shelf_id = 0
Nastavuje sa typ poľa naInitVar
(s podtypom skutočného typu poľa) signalizuje@dataclass
neurobiť toto pole do poľa datovej triedy, ale preniesť údaje ďalej do__post_init__
ako argument.
V tejto verzii našejKniha
triedy, neukladámestav
ako pole v inštancii triedy. Používame iba stav
počas fázy inicializácie. Ak to nájdemestav
bol nastavený na„Zahodené“
, nastavili smepolice_id
doŽiadne
- ale neuchovávamestav
v inštancii triedy.
Kedy používať dátové triedy Pythonu - a kedy ich nepoužívať
Jedným z bežných scenárov používania datových tried je nahradenie pomenovanej dvojice. Dátové triedy ponúkajú rovnaké správanie a ešte viac a dajú sa zmeniť na nezmeniteľné (tak ako sú pomenované n-tice) jednoduchým použitím@dataclass (frozen = True)
ako dekoratér.
Ďalším možným prípadom použitia je nahradenie vnorených slovníkov, s ktorými je ťažké pracovať, za vnorené inštancie dátových tried. Ak máte datovú trieduKnižnica
, s vlastnosťou zoznamupolice
, môžete použiť datovú trieduČitáreň
vyplniť tento zoznam a potom pridať metódy, ktoré uľahčujú prístup k vnoreným položkám (napr. kniha na polici v konkrétnej miestnosti).
Ale nie každá trieda Pythonu musí byť dátovou triedou. Ak vytvárate triedu hlavne ako spôsob, ako zoskupiť veľastatické metódy, a nie ako kontajner na dáta, nemusíte z neho robiť datovú triedu. Napríklad bežným vzorom pri syntaktických analyzátoroch je trieda, ktorá preberá abstraktný strom syntaxe, chodí po strome a na základe typu uzla odosiela volania na rôzne metódy v triede. Pretože trieda syntaktického analyzátora má len veľmi málo vlastných údajov, dátová trieda tu nie je užitočná.
Ako urobiť viac s Pythonom
- Začnite s asynchronizáciou v Pythone
- Ako používať asyncio v Pythone
- Ako používať program PyInstaller na vytvorenie spustiteľných súborov Pythonu
- Výukový program pre Cython: Ako zrýchliť Python
- Ako inteligentne nainštalovať Python
- Ako spravovať projekty Pythonu pomocou Poetry
- Ako spravovať projekty Pythonu pomocou Pipenv
- Virtualenv a venv: Vysvetlenie virtuálnych prostredí Pythonu
- Python virtualenv a venv robí a nerobí
- Vysvetlenie vlákien a podprocesov v jazyku Python
- Ako používať debugger Pythonu
- Ako používať timeit na profilovanie kódu Pythonu
- Ako používať cProfile na profilovanie kódu Pythonu
- Ako previesť Python na JavaScript (a späť)