programmatūra · 6 min · 19.07.2026

Python 3.15 dabū lazy atslēgvārdu — importu var atlikt līdz pirmajai lietošanai, un CLI rīki startē 50–70 % ātrāk

Python vadības padome pieņēma PEP 810, kas valodā ievieš jaunu atslēgvārdu lazy. Ar to importu var atlikt: modulis netiek ielādēts brīdī, kad izpildās import rinda, bet tad, kad kāds kods pirmoreiz pieskaras tā saturam. Izmaiņa nonāks Python 3.15, kas gaidāms šā gada oktobrī.

Iemesls ir tiešs. Palaižot Python programmu, pirmais imports parasti izraisa importu lavīnu — tiek ielādēti desmiti moduļu, no kuriem daļa konkrētajā palaišanā vispār netiek aiztikti. Komandrindas rīkiem tas maksā visvairāk: pat --help izsaukums samaksā laiku par bibliotēkām, kuras teksta izdrukāšanai nav vajadzīgas.

Kā izskatās jaunais pieraksts

Atslēgvārds ir tā sauktais mīkstais atslēgvārds — tas strādā tikai importu kontekstā un nesalauž mainīgos ar nosaukumu lazy. Pieraksts izskatās tā:

lazy import json
lazy from json import dumps

Šeit json modulis netiek ielādēts uzreiz. Vārdtelpā nonāk starpnieks, un pati ielāde notiek brīdī, kad kods pirmoreiz nolasa json.dumps. Pēc tam starpnieks pazūd un tā vietu ieņem īstais modulis.

Bibliotēku autoriem ir arī otrs ceļš. Modulī var uzrakstīt __lazy_modules__ = ["json"], un uz Python 3.15 vai jaunāka tur uzskaitītie importi kļūs slinki paši, it kā tiem būtu pierakstīts lazy. Uz vecākām versijām šo mainīgo interpretators vienkārši ignorē, tāpēc viens un tas pats kods strādā gan jaunajā, gan vecajā Python.

Uzvedību var mainīt arī no ārpuses. Karogs -X lazy_imports=all vai vides mainīgais PYTHON_LAZY_IMPORTS=all padara slinkus visus importus, kas to atļauj; režīms none piespiež visus atgriezties pie parastās, tūlītējās ielādes. Programmatiski to pašu dara sys.set_lazy_imports.

Cik tas dod

Skaitļi nāk no ražošanas. Meta savā Cinder izpildvidē slinkos importus lieto jau gadiem, un PEP autori atsaucas uz atmiņas ietaupījumu 30–40 % robežās un startēšanas paātrinājumu 50–70 %. Tieši startēšanas laiks ir tas, ko komandrindas rīki jūt uzreiz.

Svarīgākais mērījums tomēr ir cits: kas notiek pēc pirmās lietošanas. Atbilde ir nulle papildu izmaksu. Kad slinkais imports reiz atrisināts, adaptīvais interpretators specializē baitkodu — LOAD_GLOBAL pēc divām trim piekļuvēm pārtop par LOAD_GLOBAL_MODULE, un slinkuma pārbaude no cikla pazūd. Filtru pārbaude 278 standarta bibliotēkas moduļos deva aptuveni 0,5 % virstēriņu, ko autori sauc par praktiski nemērāmu.

Pirmā moduļa importēšana bieži izraisa tūlītēju importu kaskādi un optimistiski ielādē daudzas atkarības, kuras var nekad netikt izmantotas.

Reāls piemērs nāk no Simona Vilisona. Viņa datasette rīka startu bremzēja spraudņi, kas jau ielādes laikā importēja PyTorch, kaut lielākajai daļai izsaukumu tas nebija vajadzīgs. Ar slinkiem importiem šāda smaga atkarība tiek ielādēta tikai tad, ja to tiešām izsauc.

Kāpēc iepriekšējais mēģinājums nogāja garām

Python jau reiz mēģināja slinkos importus. PEP 690 2022. gadā piedāvāja tos ieslēgt globāli — visai ekosistēmai uzreiz — un iekabinājās vārdnīcu meklēšanā valodas kodolā. Vadības padome to noraidīja: pārāk daudz koda paļaujas uz to, ka imports notiek tieši tur, kur uzrakstīts, un globāla pārslēgšana šo pieņēmumu klusi lauztu.

PEP 810 iet pretējo ceļu. Slinks kļūst tikai tas imports, kam to skaidri norāda; visi pārējie paliek tādi, kādi bija. Atbildība ir lokāla — bibliotēkas autors izvēlas slinkumu savam kodam un neietekmē tos, kas viņa bibliotēku izmanto. Tā vietā, lai ķertos pie kodola vārdnīcām, jaunā pieeja lieto vieglus starpniekobjektus.

Ko tas maina rīkos un ikdienas kodā

Viens praktisks ieguvums skar tipizāciju. Šobrīd, lai importētu moduli tikai tipu norādēm, izstrādātāji raksta if TYPE_CHECKING: bloku, kas darbības laikā neko neielādē. Ar lazy importu tādu apvedceļu bieži var izmest: modulis tāpat netiek ielādēts, kamēr to kāds neizsauc, tāpēc tipu anotācija paliek, bet startēšanas cena pazūd.

Papildu darbs gaida palīgrīkus. Importu kārtotājam isort jau atvērts jautājums par to, kā sakārtot rindas ar jauno atslēgvārdu, un līdzīgi būs jāpielāgojas linteriem un tipu pārbaudītājiem, kuri līdz šim pieņēma, ka imports notiek uzreiz. Tie ir mehāniski labojumi, taču bez tiem rīki jaunās rindas nesaprastu pareizi.

Bibliotēku autoriem lēmums ir apzināts. Slinku importu liek tur, kur atkarība ir smaga un reti izsaukta — mašīnmācīšanās bibliotēka, tīkla klients, liels parsētājs. Kur imports ir lēts un gandrīz vienmēr vajadzīgs, to atstāj parastu. Vadības padome uzsvēra, ka noklusējums paliek nemainīgs: bez skaidra lazy vai globāla karoga viss importējas tāpat kā līdz šim.

Kur tas var iekost

Slinkums pārceļ arī kļūdas. Ja moduļa importēšana izmet kļūdu — trūkstoša atkarība, sintakses problēma, nokritis __init__ — tagad tā izmetīsies nevis programmas startā, bet tad, kad kods pirmoreiz aiztiks moduli. Kļūda var iznirt dziļi izpildē, tālu no vietas, kur uzrakstīts import.

Otra rūpe ir pavedieni. Kods, kas agrāk paredzami izpildījās viena pavediena startēšanas fāzē, tagad var nostrādāt jebkurā pavedienā — tajā, kurš gadās pirmais pieskarties modulim. Moduļu blakusefekti kļūst grūtāk paredzami. Diskusijā uz discuss.python.org viens komentētājs brīdināja, ka tas salauzīs daudz koda un ienesīs virkni kāju šāvēju. Autori uz to atbild ar dizainu: nekas nekļūst slinks pats no sevis, katrs slinkais imports ir skaidri pierakstīts.

PEP autori ir Pablo Galindo Salgado, Germans Mendess Bravo un Tomass Vauters kopā ar citiem CPython izstrādātājiem. Ielāps jau ir CPython main zarā, un pirmā versija, kur to varēs izmēģināt bez pašbūves, būs Python 3.15 beta cikls.

Avoti

komentārisaruna

Komentāri

Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.

Pievieno komentāru

Tavs e-pasts netiks publicēts. Obligātie lauki atzīmēti.

vēl no programmatūrasaistītie