Python async / wait Vysvětleno: Výukový program 2026
Async v Pythonu má pověst matoucího. Nemusí být. Jakmile internalizujete jednu větu – async umožňuje JEDNOMU vláknu spouštět více I/O-vázaných úloh prokládaných – vše ostatní následuje.
Tento tutoriál popisuje: co vlastně dělají async def a wait, když async vyhrává vs, když je to nesprávný nástroj, čtyři vzory, které používá každá asynchronní kódová základna (sekvenční, shromažďování, semafor, časový limit) a tři způsoby, jak začátečníci tiše polykají chyby.
Mentální model s jednou větou
Async v Pythonu je kooperativní souběžnost v jednom vlákně. Když váš kód narazí na wait, řízení se vrátí do smyčky událostí, která může spustit další úlohu, zatímco ta první čeká na I/O. Po dokončení I/O smyčka pokračuje v první úloze od místa, kde byla pozastavena.
To je vše. Žádná vlákna, žádné procesy, žádný paralelismus (ve smyslu CPython-with-GIL). Pouze jedno vlákno žongluje s mnoha úkoly, které tráví většinu času čekáním na síti / disku / databázi.
Asynchronní synchronizace je rychlejší, když vaše úzké místo čeká, nepracuje na počítači.
Minimálně životaschopný asynchronní program se třemi vložkami
async def hello()— deklaruje korutinu. Voláníhello()nespustí kód; vytváří objekt coroutine.wait asyncio.sleep(1)— vrátí řízení zpět do smyčky událostí na 1 sekundu.asyncio.run(hello())— vytvoří smyčku událostí a spustí korutinu až do konce.
Pravidlo: `čekat` pouze uvnitř `async def`. Volání wait v běžné funkci je SyntaxError.
Když async vyhraje (a když ne)
Async wins: I/O-bound work
Jakýkoli úkol, který tráví většinu času na nástěnných hodinách ČEKÁNÍM, je kandidátem na asynchronní:
- HTTP požadavky (externí API, scraping, webhooky)
- Databázové dotazy
- Soubor čte / zapisuje
- WebSocket / gRPC streamy
- Spotřebitelé ve frontě (Redis, RabbitMQ, Kafka)
Příklad: načtení 100 adres URL.
50-100x zrychlení nástěnných hodin pro I/O náročné práce. To je místo, kde async získává svůj rozpočet na složitost.
Async LOSES: Práce vázaná na CPU
Async vám neposkytuje paralelismus pro výpočty. Protože je kooperativní s jedním vláknem, smyčka CPU-hot loop blokuje celou smyčku událostí.
Všechny ostatní úlohy během běhu pbkdf2 strádají. Pro práci s CPU sáhněte po multiprocessing nebo concurrent.futures.ProcessPoolExecutor, ne po async.
Smíšené pracovní zatížení: run_in_executor
Pokud JEDEN krok zatěžuje CPU a zbytek je I/O, zabalte krok CPU tak, aby běžel ve fondu vláken bez blokování smyčky:
None = výchozí fond vláken. Skvělé pro volání synchronizačních knihoven třetích stran, které jsou pomalé, ale nelze je přepsat.
Čtyři vzory
1. Sekvenční — jeden úkol po druhém
Použijte, když každý požadavek závisí na výsledku předchozího.
2. asyncio.gather — vystřelte všechny najednou
Výchozí volba pro nezávislé I/O úlohy. Ale: pokud shromáždíte 10 000 úloh proti jednomu API, získáte deskriptory souborů s omezenou rychlostí nebo vyčerpáním. Zde přichází na řadu semaforový vzor.
3. Semafor — omezení souběžnosti
asyncio.Semaphore(N) nechává v každém okamžiku maximálně N úkolů za async with sem:. Ostatní úkoly jsou ve frontě. Použijte pro jakékoli externí API s limitem rychlosti nebo databázi s fondem připojení.
4. Časový limit — opusťte pomalou práci
asyncio.wait_for zruší základní úlohu po N sekundách. Nezbytné pro jakýkoli asynchronní kód, který komunikuje se sítí – nikdy nečekejte bez omezení.
Tři pasti polykající chyby
Past 1: asyncio.gather s return_exceptions=True
Užitečné, když si chcete ponechat dílčí výsledky, ale SMRTELNÉ, pokud nekontrolujete každý výsledek:
Bez kontroly chyby tiše zmizí.
Past 2: Zapomeň a zapomeň na úkoly
Pokud se background_work() zvýší, Python vydá varování při vypnutí a pokračuje dál. Pro cokoli, na čem vám záleží, uložte úlohu a čekejte ji nebo použijte asyncio.TaskGroup (3.11+), která šíří všechny chyby.
Past 3: Synchronizace kódu uvnitř asynchronně
požadavky je synchronní. I uvnitř asynchronní def blokuje requests.get celou smyčku, dokud nepřijde odpověď. Pro asynchronní HTTP použijte httpx (nebo aiohttp).
Pravidlo: nikdy nepoužívejte synchronní I/O knihovnu uvnitř asynchronního kódu. Pokud knihovna nemá asynchronní variantu, zabalte ji do run_in_executor.
asyncio.TaskGroup — způsob, jak se v roce 2026 rozšířit
Python 3.11 přidal TaskGroup, který řeší problém s ohněm a zapomeň čistě:
Strukturovaná souběžnost – žádné ztracené chyby, žádné osiřelé úkoly. Upřednostněte to před holou create_task v moderním kódu.
Příklad z reálného světa: škrabka s omezenou rychlostí
Všechny čtyři vzory v 15 řádcích: omezená souběžnost (semafor), časové limity (wait_for), explicitní chybové větve (bez polykání) a shromažďování pro rozvětvení. Zkopírujte a vložte tento tvar do jakékoli asynchronní I/O úlohy.
Async v Pythonu má skutečnou křivku učení, ale mentální model je jednoduchý: jedno vlákno, kooperativní pauzy na „čekání“, I/O se překrývají. Zvládněte gather + Semaphore + wait_for + TaskGroup a budete mít pokryto 95 % asynchronní práce, kterou kdy napíšete.
Další krok: Senior Python track má 20 praktických lekcí o asyncio, TaskGroup, aiohttp/httpx a vzorech souběžnosti výše – se skutečným Pythonem spuštěným ve vašem prohlížeči.