- Asinchroninis programavimas „Python“ kalboje leidžia kelioms įvesties / išvesties užduotims tęstis neblokuojant viena kitos per
async,awaitir įvykių ciklas. - Naudojant tokias priemones kaip
asyncio,aiohttpAsinchroninio konteksto tvarkyklės ir asinchroninio iteravimo funkcija įgalina keičiamo mastelio tinklus ir API reikalaujančius darbo krūvius. - Async puikiai tinka tinklo ir failų įvesties / išvesties technologijoms, tačiau jį reikėtų papildyti daugiaprocesinėmis arba specializuotomis paslaugomis, skirtomis užduotims, susijusioms su procesoriaus apkrovomis.
- Gera praktika – vengti iškvietimų blokavimo, riboti lygiagretumą ir tvarkyti klaidas kiekvienoje užduotyje – yra labai svarbios kuriant patikimas asinchronines programas.
Asinchroninis programavimas Python kalba iš nišinės temos tapo vienu iš pagrindinių įgūdžių visiems, kuriantiems modernias, reaguojančias programas. Jei dirbate su žiniatinklio API, mikropaslaugomis, realaus laiko ataskaitų suvestinėmis ar bet kokiomis sudėtingomis įvesties / išvesties (I/O) operacijomis, tikriausiai susidūrėte su problema, kai jūsų kodas daugiau laiko praleidžia laukdamas, nei atlikdamas realų darbą. Būtent čia ir sužiba asinchroninių metodų privalumai.
Užuot leidus programai laukti tinklo, disko ar išorinės paslaugos, asinchroninis kodas leidžia persidengti šiais laukimo laikotarpiais ir išlaikyti programą veikiančią. Šiame vadove mes išsamiai išnagrinėsime, kaip asinchroninis metodas veikia Python kalboje, kokias problemas jis išsprendžia, kada jis tikrai padeda, o kada tai netinkamas įrankis, ir pateiksime konkrečių pavyzdžių, kaip... async, await, asyncio ir populiarias asinchronines bibliotekas, pvz. aiohttp.
Kas yra asinchroninis programavimas Python kalboje?
Iš esmės asinchroninis programavimas yra būdas struktūrizuoti kodą taip, kad kelios užduotys galėtų tęsti savo darbą neblokuodamos viena kitos, net jei jos naudoja vieną operacinės sistemos giją. Klasikiniame sinchroniniame stiliuje kiekviena operacija baigiama dar prieš prasidedant kitai: iškviečiama API, palaukiama, išanalizuojamas atsakymas ir tik tada tęsiama. Naudodami asinchroninį kodą, galite suaktyvinti kelias ilgai veikiančias operacijas ir leisti „Python“ perjungti jas, kai viena iš jų tiesiog laukia.
„Python“ įgyvendina šį modelį naudodamas specialios sintaksės ir bendradarbiaujančio planuoklio, sukurto aplink įvykių ciklą, derinį. Du raktiniai žodžiai, kurie visa tai atveria, yra async bei await: funkcijas pažymite kaip asinchronines naudodami async def, ir jūs sustojate jų viduje su await kaskart, kai atliekate operaciją, kuri gali grąžinti valdymą įvykių ciklui.
An async def Funkcija negrąžina vertės tiesiogiai; ji grąžina korutininį objektą, kuris vaizduoja skaičiavimą, kurį galima suplanuoti ir laukti. Kai naudojate await Šios funkcijos viduje Python sustabdo dabartinį korutiną ir leidžia vykdyti kitas laukiančias užduotis, kol bus baigta laukiama operacija (pvz., tinklo užklausa), o tada vykdymas atnaujinamas iškart po to. await.
Tai labai svarbu: asinchroninis „Python“ kodas paprastai vis dar yra vienagijas, bet lygiagretus ta prasme, kad kelios operacijos vyksta persidengiančiais laiko intervalais. Kol viena užduotis laukia įvesties/išvesties, kita gauna procesoriaus laiko. Štai kodėl asinchroninis režimas puikiai tinka įvesties/išvesties apribotoms darbo krūviams, tačiau stebuklingai nepaspartina darbo, kuriame daug procesoriaus naudojama.
Konkreti analogija: šachmatų parodos ir laukimo laikas
Klasikinė analogija, naudojama Python bendruomenėje, paaiškinant lygiagretų ir nuoseklų vykdymą, yra kilusi iš lygiagretaus šachmatų pasirodymo. Įsivaizduokite didmeistrę, žaidžiančią prieš 24 mėgėjus. Ji gali vesti renginį dviem skirtingais būdais, imituodama sinchroninę ir asinchroninę strategijas.
Sinchroninėje versijoje ji atsisėda su vienu priešininku ir sužaidžia tą vieną žaidimą nuo pradžios iki pabaigos, prieš pereidama prie kito stalo. Kiekvienas jos ėjimas trunka 5 sekundes, o kiekvienas mėgėjas mąstymui skiria apie 55 sekundes. Įprastame žaidime būna 30 ėjimų pasikeitimų (taigi, iš viso 60 ėjimų). Tai reiškia, kad kiekvienas žaidimas trunka (55 + 5) × 30 = 1800 sekundžių, maždaug 30 minučių. Sužaidus 24 žaidimus, visas renginys trunka 12 valandų.
Asinchroninėje versijoje ji vaikšto po kambarį ir atlieka po vieną ėjimą prie kiekvienos lentos, o tada iškart pereina prie kitos, o dabartinis priešininkas galvoja apie savo atsakymą. Vienas ėjimų raundas per 24 lentas trunka 24 × 5 = 120 sekundžių arba 2 minutes. Po 30 tokių raundų visas žaidimų rinkinys sužaidžiamas maždaug per 3600 sekundžių, t. y. 1 valandą.
Svarbiausia išvada yra ta, kad jos grojimo greitis niekada nepasikeitė; pasikeitė tik tai, kaip ji išnaudojo priešininkų laukimo laiką. Asinchroninis Python kodas vadovaujasi tuo pačiu principu: jis nepagreitina įvesties / išvesties, bet užtikrina, kad jūs darote ką nors naudingo, kol kitu atveju tektų laukti tinklo, disko ar bet kokio išorinio ištekliaus.
Sinchronizavimo ir asinchroninių užklausų palyginimas: realaus pasaulio pavyzdys su API
Vienas iš labiausiai paplitusių asinchroninio apdorojimo naudojimo atvejų Python kalboje yra darbas su išorinėmis API sąsajomis, kur kiekviena užklausa gali lengvai užtrukti šimtus milisekundžių ar daugiau. Iliustracijai įsivaizduokite, kad norite sužinoti kelių „GitHub“ paskyrų sekėjų skaičių naudodami jų viešąją API.
Paprastas sinchroninis metodas naudotų populiarų blokuojantį HTTP klientą, pvz. requests. Kiekvienam vartotojo galiniam taškui atliktumėte GET užklausą cikle, nuskaitytumėte JSON naudingąją apkrovą, išskleistumėte followers lauką ir jį atsispausdinti arba išsaugoti. Tai paprasta ir suprantama, tačiau turi trūkumų: kiekvienai apdorojamai sąskaitai programa atlieka užklausą ir tik laukia atsakymo, prieš pradėdama kitą.
Taigi, jei patikrinsite tris vartotojus, pvz. api.github.com/users/python, api.github.com/users/google bei api.github.com/users/firebase, kodas siunčia pirmąją užklausą, blokuoja, kol „GitHub“ atsako, tada pereina prie antrosios užklausos ir taip toliau. Turint saujelę vartotojų, tai gali būti priimtina, bet sąrašui išaugus iki šimtų ar tūkstančių, bendras apdorojimo laikas pailgėja, nes programa didžiąją savo gyvavimo laiko dalį praleidžia neveikdama, laukdama nuotolinio serverio.
Norėdami pagreitinti procesą, galite pereiti prie asinchroninio diegimo, sukurto ant asyncio ir asinchroninį ryšį palaikantį HTTP klientą, pvz. aiohttp. Tame modelyje paleidžiamos kelios korutininės užduotys, kurios beveik vienu metu siunčia HTTP užklausas. Įvykių ciklas laukia atsakymų iš bet kurios iš jų ir atnaujina kiekvieną užduotį, kai tik gaunami duomenys, o ne laukia, kol viena užklausa bus visiškai įvykdyta, prieš pradedant kitą.
Lyginant šiuos du metodus, asinchroninė versija paprastai laimi didele persvara, ypač didėjant vartotojų skaičiui. Laikas vienai užklausai nesikeičia, tačiau bendras laikas visiems rezultatams gauti smarkiai sumažėja, nes tvarkote daug ryšių vienu metu, o ne nuosekliai.
Pagrindinės sąvokos: korutinos, įvykių ciklas, užduotys ir ateities planai
Po gaubtu šiuolaikinis asinchroninis Python sukasi apie kelis pagrindinius elementus, kuriuos daugiausia teikia asyncio modulis. Šių sąvokų supratimas padarys likusią ekosistemos dalį daug mažiau paslaptingą ir padės jums sukurti tvirtas asinchronines architektūras.
Korutina yra specialios rūšies funkcija, kuri gali pristabdyti ir atnaujinti savo vykdymą. Šiandienos sintaksėje jūs apibrėžiate vieną su async defKai jį iškviečiate, gaunate korutininį objektą, kurio reikia laukti arba suplanuoti; jis nevykdomas iš karto, kaip įprasta funkcija. Viduje, kai naudojate await Laukiamo korutino atveju (kito korutino, užduoties, ateities ir pan.) „Python“ sustabdo to korutino veikimą, kol laukiama operacija bus baigta.
Įvykių ciklas yra orkestratorius, kuris seka visus laukiančius korutinus, įvesties / išvesties operacijas ir laikmačius ir nusprendžia, kuris kodo fragmentas vykdomas bet kuriuo metu. Istoriškai ciklą reikėjo gauti ir valdyti aiškiai per asyncio.get_event_loop(), tačiau šiuolaikiniame Python kode pageidaujamas modelis yra leisti asyncio.run() sukurkite, paleiskite ir uždarykite ciklą už jus aplink aukščiausio lygio asinchroninę funkciją, pvz. main().
Užduotys yra apvalkalai aplink korutinas, kurie nurodo įvykių ciklui suplanuoti jų vykdymą. Galite juos laikyti lengvais darbais: ciklas gali įterpti eigą tarp daugelio užduočių nesukurdamas kelių gijų. Paprastai užduotis kuriate su asyncio.create_task() arba pasikviesdami pagalbininkus, pvz. asyncio.gather(), kurie viduje valdo užduočių rinkinį.
Ateities sandoriai (Futures) žymi rezultatus, kurie taps prieinami vėliau, panašiai kaip „Promises“ „JavaScript“ kalboje. Ir užduotys, ir ateities įvykiai yra laukiami objektai: galite await juos sustabdyti, kol bus baigta pagrindinė operacija. Šis suvienodintas protokolas labai supaprastina orkestravimo kodą, nes asinchroninių srautų kūrimas susiveda į tinkamų objektų laukimą tinkama tvarka.
Asinchroninės sintaksės praktinis pritaikymas: async, await, async with bei async for
Geriausios async Raktinis žodis „“ neapsiriboja funkcijų apibrėžimais; jis taip pat apima konteksto tvarkykles ir ciklus, kad asinchroniniame pasaulyje galėtų dalyvauti sudėtingesni modeliai. Žinant šią išplėstinę sintaksę, galite rašyti elegantišką kodą, apimantį tinklo ryšius, sesijas, srautus ir pasirinktinius protokolus.
Dažniausia forma yra async def, kuri apibrėžia asinchroninę funkciją (korutinų gamyklą). Tokios funkcijos viduje jūs gausiai naudosite await kai iškviečiate kitą korutiną arba laukiamą operaciją, pvz. asyncio.sleep(), asinchroninę HTTP užklausą arba asinchroninę duomenų bazės užklausą. Atminkite, kad negalite naudoti await tiesiai aukščiausiame scenarijaus lygyje; jis turi būti jo viduje async def.
Nors galite susigundyti paskambinti time.sleep() jūsų korutinoje dėl vėlavimų, tai visiškai paneigtų asinchroninio metodo naudojimo prasmę. time.sleep() blokuoja visą giją, įskaitant įvykių ciklą, todėl tuo metu negali būti vykdoma jokia kita asinchroninė užduotis. Vietoj to turite naudoti neblokuojantį atitikmenį. asyncio.sleep(), kuris grąžina valdymą ciklui, kol laikmatis skaičiuoja laiką atgal.
Python taip pat palaiko asinchroninius konteksto tvarkytuvus per async with, įgyvendinama apibrėžiant specialius metodus __aenter__ bei __aexit__. Tai ypač patogu dirbant su objektais, kuriems reikalinga švari sąrankos ir išardymo seka, apimanti asinchronines operacijas, pvz., tinklo sesijos atidarymas arba asinchroninio ištekliaus gavimas. Tipiškas pavyzdys yra valdymas. aiohttp.ClientSession arba atskira HTTP užklausa naudojant async with blokai, o ne skambinimas rankiniu būdu close().
Galiausiai, asinchroninė iteracija yra atskleidžiama per async for, kuris remiasi magijos metodais __aiter__ bei __anext__ aprašyta PEP 492. Asinchroniniai iteratoriai ir asinchroniniai generatoriai leidžia laikui bėgant gauti elementų, naudojant await iteracijos proceso viduje, kuris puikiai tinka srautiniam duomenų perdavimui, kurie palaipsniui gaunami tinklu arba iš kito asinchroninio šaltinio.
Kelių užduočių vykdymas vienu metu su asyncio
Tikroji asinchroninio programavimo galia išryškėja, kai kelias įvesties / išvesties užduotis vykdote vienu metu, o ne vieną po kitos. Python asinchroninėje ekosistemoje pagrindiniai įrankiai tam yra asyncio.create_task() bei asyncio.gather(), kurie abu suplanuoja korutinas įvykių cikle.
Su asyncio.gather(), galite vienu metu paleisti kelias korutinas ir laukti, kol jos visos bus baigtos, gaudamos jų rezultatus kaip sąrašą arba rinkinį. Tai ypač dažnai pasitaiko atliekant HTTP iškvietimų paketus, duomenų bazės užklausas ar bet kokias pasikartojančias asinchronines operacijas. gather() įtraukia kiekvieną korutiną į užduotį ir užtikrina, kad jos visos būtų atliktos.
Jei grįšite prie „GitHub“ profilių gavimo pavyzdžio, bet jį pertvarkysite naudodami aiohttp bei asyncio.gather(), galiausiai turėsite tris iškvietimus į tokią funkciją kaip fetch_user() paleidžiami vienu metu. Kiekviena užduotis pradeda savo HTTP užklausą, perduoda valdymą laukdama duomenų ir, gavusi atsakymą, tęsia jo analizę. Vartotojo požiūriu, visi trys rezultatai rodomi maždaug tuo pačiu metu.
Tačiau yra atvejų, kai nenorite vienu metu atlikti tūkstančių ar milijonų užduočių, nes tai gali perkrauti jūsų kompiuterį arba pasiekti išorinius greičio apribojimus. Įprastas modelis yra apriboti lygiagretumą tik apdorojant MAX_TASKS operacijas vienu metu, naudodami semaforus, apribotus telkinius arba rankinį paketavimo logiką asinchroninio darbo eigoje.
Kitas svarbus aspektas, kai vienu metu vykdomos kelios užduotys, yra tai, kaip tvarkomos klaidos; leisti vienai nepavykusiai užklausai sugadinti visą paketą realiose programose retai kada priimtina. Idealiu atveju jūsų asinchroninis orkestravimas turėtų aptikti ir valdyti išimtis kiekvienai užduočiai, galbūt jas užregistruoti, selektyviai bandyti dar kartą arba grąžinti dalinius rezultatus, tuo pačiu išsaugant likusią paketo dalį.
Lygiagretumo valdymas: privalumai ir trūkumai
Svarbu atskirti lygiagretumo ir paralelizmo idėjas, nes asinchroninis Python pateikia pirmąją, bet nebūtinai antrąją. Lygiagretumas reiškia, kad kelios užduotys atliekamos persidengiančiais intervalais, o lygiagretumas reiškia, kad jos tiesiogine prasme veikia tuo pačiu metu keliuose procesoriaus branduoliuose.
Tipinis asinchroninis kodas, naudojant asyncio nesukuria kelių OS gijų; vietoj to, ji multipleksuoja užduotis viename gijoje pagal tai, kada kiekviena iš jų yra blokuojama įvesties / išvesties metu, panašiai kaip programación asíncrona en Node.js. Štai kodėl jis taip gerai pritaikomas tūkstančiams jungčių: konteksto perjungimas yra pigus, nes jis yra kooperatyvus ir valdomas įvykių ciklo, o ne operacinės sistemos.
Šis dizainas turi iššūkių, ypač susijusių su koordinavimu ir išimčių tvarkymu. Kadangi jūsų logika dabar yra paskirstyta keliose korutinose, kurios susikerta laike, turite būti atidesni dalindamiesi būsena, skleisdami klaidas ir valydami išteklius. Klaidos, tokios kaip „pamiršta“ await, užduotys, kurios niekada nelaukiamos, arba išimtys, tyliai praryjamos foninėse užduotyse, gali būti subtilios ir sunkiai derinamos.
Kad asinchroninio kodo bazė būtų lengvai prižiūrima, turėtumėte laikytis patikimų inžinerinių praktikų: sutelkti korutinas į vieną atsakomybę, centralizuoti klaidų tvarkymą, kai įmanoma, ir pridėti tinkamą žurnalą, kad suprastumėte, kas vyksta vykdymo metu. Geri įrankiai ir aiškios konvencijos labai padeda išvengti lenktynių sąlygų tipo problemų ar išteklių nutekėjimo, net ir vienos gijos asinchroninėje aplinkoje.
Kada asinchroninis kodas tikrai padeda (ir kada ne)
Asinchroninis programavimas yra neįtikėtinai efektyvus įvesties / išvesties apkrovoms, tačiau tai nėra stebuklinga priemonė kiekvienai našumo problemai. Pirmasis bet kokių optimizavimo pastangų žingsnis turėtų būti nustatyti, ar jūsų kliūtys kyla dėl įvesties / išvesties, ar dėl procesoriaus apkrautų skaičiavimų.
Jei jūsų programa didžiąją laiko dalį praleidžia laukdama tinklo atsakymų, skaitydama ir rašydama failus, teikdama užklausas duomenų bazėms arba bendraudama per lizdus, asinchroninis protokolas beveik neabejotinai yra tinkamas pasirinkimas. Tipiniai pavyzdžiai: žiniatinklio API, kurios bendrauja su keliomis išorinėmis paslaugomis, ETL kanalai, kurie vienu metu skaito ir rašo iš kelių duomenų šaltinių, ir mikropaslaugos, kurios palaiko daug vienu metu veikiančių klientų ryšių.
Kita vertus, jei jūsų darbo krūvį daugiausia sudaro sudėtingos procesoriaus operacijos, pvz., skaičių apdorojimas, vaizdų apdorojimas ar sudėtingos simuliacijos, vien asinchroninis veikimas nepaspartins darbo. Tokiais atvejais GIL (Global Interpreter Lock) vis dar riboja, kas gali veikti lygiagrečiai viename Python procese. Paprastai geresnių rezultatų gausite naudodami kelių procesų apdorojimą, vietinius plėtinius arba specializuotas posistemes.
Įmonių aplinkoje pragmatiška strategija yra derinti šiuos metodus: naudoti asinchroninius ir asinchroniškai suderinamus SDK debesijos paslaugoms (AWS, „Azure“ ir kitoms), siekiant sumažinti delsą ir padidinti pralaidumą, tuo pačiu metu deleguojant procesoriaus apkrovą reikalaujantį darbą atskiriems procesams, darbuotojams arba valdomoms skaičiavimo paslaugoms. Tokiu būdu išnaudojate kiekvieno įrankio stipriąsias puses, o ne kovojate su kalbos vykdymo aplinka.
Geriausia asinchroninio Python rašymo praktika
Kai pradėsite plačiau taikyti asinchroninį ryšį, tam tikri modeliai ir įpročiai padės išvengti dažniausiai pasitaikančių klaidų. Jie taip pat padaro jūsų kodą aiškesnį komandos nariams, kurie dar gali būti nelabai susipažinę su asinchroninės ekosistemos sistema.
Pagrindinė taisyklė – vengti iškvietimų blokavimo asinchroniniuose kodo keliuose. Tai reiškia, kad reikia pakeisti tokius dalykus kaip time.sleep() su await asyncio.sleep()ir būti atsargiems su bibliotekomis, kurios nesiūlo su asinchroniniu suderinamumu suderinamų API. Jei trečiosios šalies paketas yra visiškai sinchroninis, jo iškvietimas iš korutinos gali užblokuoti įvykių ciklą ir sugadinti lygiagretumo privalumus.
Kai atliekate kelias nepriklausomas įvesties / išvesties operacijas, pageidautina jas vykdyti vienu metu, naudojant tokias programas kaip asyncio.gather() arba užduočių telkiniai, kuriuos riboja maksimalus lygiagretumo lygis. Šis modelis padidina pralaidumą, tuo pačiu išlaikant atvirų ryšių arba vykdomų užklausų skaičiaus kontrolę.
Kaip projektavimo gaires, stenkitės, kad korutinos būtų gana mažos ir sutelktos į aiškią atsakomybę, panašiai kaip kurtumėte funkcijas švariame sinchroniniame kode. Didelius monolitinius korutinus, kuriuose derinamas tinklas, verslo logika ir klaidų tvarkymas, greitai tampa sunku išbandyti ir pagrįsti, ypač kai kas nors nepavyksta.
Galiausiai, visada patikrinkite, ar ekosistemos komponentai, kuriais remiatės, tikrai palaiko asinchroninį naudojimą. Daugelyje populiarių bibliotekų yra atskiri asinchroniniai klientai arba dedikuoti submoduliai; kitos vis tiek gali blokuoti, net jei reklamuoja „asinchronines“ funkcijas. Atidžiai perskaitę dokumentaciją ir atlikę nedidelius testus, išvengsite subtilių našumo pokyčių.
Praktinio naudojimo scenarijai ir architektūros idėjos
Realaus pasaulio programinės įrangos projektuose asinchroninis dizainas puikiai veikia įvairiose architektūrose – nuo tradicinių žiniatinklio serverių iki pažangiausių dirbtinio intelekto valdomų sistemų. Vienijantis elementas visada yra poreikis apdoroti daug įvesties / išvesties operacijų, negaištant laiko laukimui.
Vienas klasikinis scenarijus yra žiniatinklio paslauga, kuriai reikia iškviesti kelias išorines API, kad sukurtų vieną atsakymą klientui. Naudodama asinchroninį protokolą, paslauga gali vienu metu suaktyvinti visas siunčiamas užklausas ir surinkti galutinį naudingąjį apkrovą, kai tik kiekviena dalis gaunama, taip žymiai sutrumpinant bendrą atsakymo laiką. Tai įprasta mikropaslaugų architektūrose ir integracijose su mokėjimo šliuzais, socialiniais tinklais ar analizės platformomis.
Kitas svarbus naudojimo atvejis yra duomenų inžinerija: vamzdynai ir ETL užduotys dažnai sąveikauja su keliomis duomenų bazėmis, failų sistemomis arba debesies saugyklų segmentais lygiagrečiai. Skaitydami iš kelių šaltinių vienu metu ir įrašydami rezultatus, kai tik jie bus paruošti, sumažinsite bendrą delsą ir geriau išnaudosite turimą pralaidumą, ypač dirbant su debesies saugykla arba REST pagrindu veikiančiomis duomenų API.
Async taip pat puikiai dera su verslo analitikos ataskaitų suvestinėmis ir įrankiais, tokiais kaip „Power BI“, kur serveriai turi kaupti duomenis iš skirtingų paslaugų neblokuodami ilgai veikiančių HTTP ryšių. Kurkite savo pasirinktinius API sluoksnius arba integracijos mikropaslaugas naudodami asyncio gali pagerinti suvokiamą reagavimą ir pralaidumą esant apkrovai.
Įmonės, kurios specializuojasi nestandartinėje programinėje įrangoje, dirbtiniame intelekte, kibernetiniame saugume ir debesų kompiuterijos konsultacijose, dažnai labai pasikliauja asinchroniniais metodais, kad organizuotų darbo eigas, kurios iškviečia dirbtinio intelekto modelius, registruoja įvykius, stebi grėsmes ir bendrauja su debesų valdymo plokštumomis. Asinchroninio įvesties/išvesties derinimas orkestravimui su atskirais CPU optimizuotais darbuotojais sunkiems darbams atlikti yra įprastas vidinis modelis, leidžiantis sukurti keičiamo dydžio ir prižiūrimas sistemas.
Daugeliui kūrėjų ir komandų pirmas žingsnis yra tiesiog įdiegti asinchroninį metodą tose programos dalyse, kurios aiškiai rodo „įvesties / išvesties apribojimus“, o tada kartoti veiksmus, kai nauda tampa akivaizdi ir komanda įgyja pasitikėjimo paradigmomis ir įrankiais.
Galiausiai, asinchroninis programavimas Python kalboje yra apie išmintingą laukimo laiko panaudojimą: struktūrizuojant savo kodą aplink async, await, korutinas ir įvykių ciklą, galite kurti programas, kurios veikia greičiau, geriau keičiasi esant apkrovai ir maksimaliai išnaudoja turimus išteklius, ypač dirbant su tinklais, failais ir išorinėmis paslaugomis.
