آموزش ماژول asyncio – بهبود عملکر با gather

Please login to bookmark Close

برای اینکه چند تسک را همزمان با یکدیگر شروع و تمام کنید می‌توانید از متد gather استفاده کنید.

import asyncio

async def download_file(file_name):
    assert '%' not in file_name, "Bad file name!"
    print(f'dowload {file_name} started')
    await asyncio.sleep(2)
    print(f'dowload {file_name} finished')
    return file_name

async def manage_downloads():
    t1 = asyncio.create_task(download_file('test1.txt'))
    t2 = asyncio.create_task(download_file('text2.txt'))

    res = await asyncio.gather(t1, t2)
    print(res)

asyncio.run(manage_downloads())

توضیح کد بالا:

  • خط ۳ تا ۸: یک coroutine تعریف کرده‌ایم که نام یک فایل را می‌گیرد و اگر کارکتر % در نامش نداشت آن را دانلود می‌کند.
  • خط ۱۹ تا ۱۵: یک coroutine تعریف کرده‌ایم که coroutine های دیگر را در خود اجرا می‌کند.
    • خط ۱۴: در این قسمت با استفاده از gather همزمان t1 و t2 را اجرا کرده‌ایم.

تعامل با ارور ها

اگر نام فایل حاوی % باشد coroutine ارور می‌دهد. به تکه کد زیر توجه کنید:

import asyncio

async def download_file(file_name):
    assert '%' not in file_name, "Bad file name!"
    print(f'dowload {file_name} started')
    await asyncio.sleep(2)
    print(f'dowload {file_name} finished')
    return file_name

async def manage_downloads():
    t1 = asyncio.create_task(download_file('test.txt'))
    t2 = asyncio.create_task(download_file('text%.txt'))

    res = await asyncio.gather(t1, t2)
    print(res)

asyncio.run(manage_downloads())

خروجی این کد شبیه زیر خواهد بود:

dowload test.txt started
Traceback (most recent call last):
  File "/home/username/workspace/concurrency/01.py", line 17, in <module>
    asyncio.run(manage_downloads())
  File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/username/workspace/concurrency/01.py", line 14, in manage_downloads
    res = await asyncio.gather(t1, t2)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/username/workspace/concurrency/01.py", line 4, in download_file
    assert '%' not in file_name, "Bad file name!"
           ^^^^^^^^^^^^^^^^^^^^
AssertionError: Bad file name!

با کمی تغییر در کد بالا می‌توان به کد زیر رسید که به این شکل خطا نمی‌دهد.

import asyncio

async def download_file(file_name):
    assert '%' not in file_name, "Bad file name!"
    print(f'dowload {file_name} started')
    await asyncio.sleep(2)
    print(f'dowload {file_name} finished')
    return file_name

async def manage_downloads():
    t1 = asyncio.create_task(download_file('test.txt'))
    t2 = asyncio.create_task(download_file('text%.txt'))

    res = await asyncio.gather(t1, t2, return_exceptions=True)
    print(res)

asyncio.run(manage_downloads())

خروجی این کد شبیه به زیر خواهد بود:

dowload test.txt started
dowload test.txt finished
['test.txt', AssertionError('Bad file name!')]
Please login to bookmark Close
نظرات

دیدگاهتان را بنویسید

فهرست مطالب

سرفصل دوره

تمرین

این قسمت تمرین ندارد!

پاسخ تمرین ها

هنوز برای تمرین‌های این قسمت پاسخی ثبت نشده است!

اشتراک گذاری

چرا بهتره از فیلترشکن استفاده کنید؟

من همه ویدئو ها و پادکست های کُدباز رو توی یوتیوب و ساندکلود و پلتفرم هایی آپلود می‌کنم که اغلب فیلتر هستند.

اغلب آموزش‌ها ویدئو و پادکست دارند. پس اگر می‌خواهید از محتوای سایت بیشترین استفاده رو ببرید نیاز به فیلتر شکن دارید.

توجه داشته باشید که برای خرید از فروشگاه بهتره فیلتر شکن رو خاموش کنید.

تنظیمات

انتخاب زبان
تغییر تم