Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

Tôi có phương pháp sau đây tạo dữ liệu cho tôi:

async def generate_url(self, video_id):
    data = await self.s3.generate_presigned_url(...video_id...)
    return data

def convert_to_json(self, urls):
    ids = [self.generate_url(url) for url in urls]
    ...

Làm thế nào để chờ chính xác

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
6 trong
async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
7?

Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

VMATM

Phù bằng vàng 27.6K1717 gold badges81 silver badges122 bronze badges

Hỏi ngày 4 tháng 4 năm 2017 lúc 18:58Apr 4, 2017 at 18:58

2

Bạn có thể sử dụng trình bao bọc

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
8 xung quanh danh sách các tác vụ:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)

Hoặc, nếu bạn không thể đánh dấu phương thức

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
7 là
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0, hãy đợi nó đồng bộ:

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))

Ngoài ra, bạn có thể cố gắng triển khai trình lặp

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0 và sử dụng nó với cú pháp
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2, một cái gì đó như thế này:

class Loader:
    def __init__(self, urls):
        self._urls = iter(urls)

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def __aiter__(self):
        return self

    async def __anext__(self):
        try:
            url = next(self._urls)
        except StopIteration:
            raise StopAsyncIteration
        data = await self.generate_url(url)
        return data

async for id in Loader(urls):
    print(id)

Đã trả lời ngày 5 tháng 4 năm 2017 lúc 21:25Apr 5, 2017 at 21:25

Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

VMATMVMATMVMAtm

Phù bằng vàng 27.6K1717 gold badges81 silver badges122 bronze badges

Hỏi ngày 4 tháng 4 năm 2017 lúc 18:58

import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])

Enjoy!

Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

VMATM

Phù bằng vàng 27.6K1717 gold badges81 silver badges122 bronze badges

Hỏi ngày 4 tháng 4 năm 2017 lúc 18:58Apr 4, 2017 at 19:14

Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

Bạn có thể sử dụng trình bao bọc

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
8 xung quanh danh sách các tác vụ:Yuval Pruss

Hoặc, nếu bạn không thể đánh dấu phương thức

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
7 là
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0, hãy đợi nó đồng bộ:12 gold badges40 silver badges65 bronze badges

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))

loop = asyncio.get_event_loop()
ids = loop.run_until_complete(asyncio.gather(*[self.generate_url(url) for url in urls]))

Ngoài ra, bạn có thể cố gắng triển khai trình lặp

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0 và sử dụng nó với cú pháp
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2, một cái gì đó như thế này:

ids = await asyncio.gather(*[self.generate_url(url) for url in urls])

Đã trả lời ngày 5 tháng 4 năm 2017 lúc 21:25Apr 5, 2017 at 22:03

VMATMVMATMUdi

Đối với tôi, nó đã làm việc như thế này:9 gold badges94 silver badges124 bronze badges

Hướng dẫn python await inside for loop - python đang chờ bên trong vòng lặp for

Asyncio đã mang lại sự hỗ trợ cho I/O không đồng bộ với vòng lặp sự kiện đến Python 3. Ban đầu, nó chỉ là một mô -đun được xây dựng trên đỉnh của từ khóa

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
3 được sử dụng với các trình tạo. Điều này đã thay đổi với việc phát hành Python 3.5 đã giới thiệu các từ khóa
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0 và
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
5, cho phép biến mã Python 3.4 này:

@asyncio.coroutine
def get(self, *args, **kwargs):
    yield from self.wait_for_token()
    return self.client.get(*args, **kwargs)

Vào mã Python 3.5 này:

async def get(self, *args, **kwargs):
    await self.wait_for_token()
    return self.client.get(*args, **kwargs)

Vì vậy, đó là một cải tiến gia tăng tốt đẹp! Nhưng Python 3.5 cũng mang lại sự hỗ trợ cho các nhà quản lý bối cảnh không đồng bộ (

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
6) và các vòng không đồng bộ (
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2). Tôi tin rằng hai người đó cũng xứng đáng được biết đến và được sử dụng! Thật vậy, họ thêm sức mạnh biểu cảm thực sự khó đạt được trong Python 3.4. Trong bài đăng này, tôi sẽ tập trung vào
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2.

Thật vậy, khi tôi bắt đầu tìm kiếm thông tin về các vòng lặp không đồng bộ, thông tin tôi thấy là khó hiểu. Tôi đã gõ

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
9 vào công cụ tìm kiếm và kết quả hàng đầu là PEP 492, cung cấp quá nhiều chi tiết cho người dùng tính năng này và chỉ xem xét Python 3.5 làm phức tạp tình huống như chúng ta sẽ thấy dưới đây. Nhưng nếu bạn có thể sử dụng Python 3.6 trở lên, bạn sẽ gặp may! Các vòng không đồng bộ sẽ dễ sử dụng hơn nhiều.

Python 3.6+

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2 vòng lặp là một phần mở rộng tự nhiên của các vòng lặp thông thường trong Python. Chúng ta hãy sử dụng ví dụ về API HTTP được phân trang, trả về trang sau trang. Đây là cách một sự đồng bộ thông thường cho vòng lặp sẽ hoạt động:

def get_docs():
    page = fetch_page()
    while page:
        for doc in page:
            yield doc
        page = fetch_page()

for doc in get_docs():
    pass  # work on doc

Bây giờ, một sự không đồng bộ cho vòng lặp sẽ thực sự giống nhau. Như thường lệ với Asyncio, bạn chỉ cần thêm các từ khóa Async/Await ở đúng nơi:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
0

Và đó là nó! Mã của bạn bây giờ không đồng bộ. Không có gì kỳ diệu, nó chỉ là một vòng lặp về kết quả mang lại

class Loader:
    def __init__(self, urls):
        self._urls = iter(urls)

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def __aiter__(self):
        return self

    async def __anext__(self):
        try:
            url = next(self._urls)
        except StopIteration:
            raise StopAsyncIteration
        data = await self.generate_url(url)
        return data

async for id in Loader(urls):
    print(id)
1. Thứ tự thực thi giống như trong trường hợp không đồng bộ, ngoại trừ trong các cuộc gọi
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
5, mã không liên quan khác có thể thực thi.

.

Python 3.5

Tuy nhiên, bạn có thể bị mắc kẹt với Python 3.5, ví dụ nếu bạn chỉ sử dụng các phiên bản Python được cung cấp bởi Ubuntu 16.04 LTS. Hoặc bạn muốn hiểu cách các máy lặp không đồng bộ hoạt động dưới mui xe.

Trong Python 3.5, bạn không thể sử dụng

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
3 trong hàm
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0. Thật vậy, chức năng
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
0 ban đầu được triển khai bằng cách sử dụng
import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
3 trong Python 3.4 và giới hạn này chỉ được xóa trong Python 3.6. Vì vậy, mã trên sẽ không hoạt động. Thay vào đó, bạn cần tái tạo
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
1 bằng cách sử dụng một lớp, mức thấp hơn, phức tạp hơn và dài hơn. Đây là những gì nó trông giống như:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
1

Chúng ta cần lưu trữ kết quả của mã

import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
2 trong bộ đệm để có thể trả lại từng cái một khi cần thiết. Để bảo tồn thứ tự, chúng tôi cần hàng đợi từ đầu tiên (FIFO), có thể dễ dàng thực hiện với
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
3 trong Python.

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
2

import asyncio

def convert_to_json(self, urls):
    loop = asyncio.get_event_loop()
    tasks = [self.generate_url(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
2 Các vòng lặp Sử dụng giao thức
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
5: chúng cần một đối tượng với phương thức
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
5. Đối tượng trả về bằng
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
5 nên có phương thức
import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
8 sẽ trả về từng đối tượng một:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
3

Nếu bộ đệm trống, chúng tôi cố gắng lấp đầy nó. Nếu nó vẫn trống, đây là kết thúc của vòng lặp, vì vậy chúng tôi dừng lặp lại.

Bây giờ, nếu bộ đệm không trống, chúng ta có thể lấy giá trị cuối cùng được thêm vào nó (hãy nhớ rằng chúng ta coi bộ đệm của mình là hàng đợi.) Chúng ta chỉ còn lại phương thức

import asyncio

class A:
    def __init__(self):
        pass

    async def generate_url(self, video_id):
        data = await self.s3.generate_presigned_url(...video_id...)
        return data

    def add_to_ids(self, id):
        ids.append(id.result())

    def convert_to_json(self, urls):
        loop = asyncio.get_event_loop()

        ids = []
        tasks = []

        for url in urls:
            task = asyncio.ensure_future(self.generate_url(url))
            task.add_done_callback(self.add_to_ids)
            tasks.append(task)
        tasks = asyncio.gather(*tasks)

        loop.run_until_complete(tasks)
        loop.close()

a = A()
a.convert_to_json([1, 2, 3])
9:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
4

Woah! Rất nhiều nồi hơi.

Python 3.5 + async_generator

Ngoài ra, bạn có thể có một cái gì đó gần với phiên bản Python 3.6 bằng thư viện Async_generator của bên thứ ba cho phép bạn viết:

async def convert_to_json(self, urls):
    tasks = [self.generate_url(url) for url in urls]
    await asyncio.wait(tasks)
5

Điều này gần hơn nhiều với phiên bản Python 3.6! Cảm ơn Nathaniel J. Smith đã có 1/ viết thư viện và 2/ đã đề cập đến nó trong các bình luận!

Cuối cùng, nếu bạn vẫn đang sử dụng Python 3.4, thì bạn còn chờ gì để nâng cấp?

Nếu bạn thích bài đăng này, bạn có thể thích:

  • Làm thế nào để bạn đánh giá các cuộc gọi giới hạn với aiohttp?
  • Làm thế nào để bạn giới hạn việc sử dụng bộ nhớ với asyncio?

Bạn có thể chờ đợi bên trong một vòng lặp không?

Bạn cần đặt vòng lặp vào hàm Async, sau đó bạn có thể sử dụng Await và vòng lặp dừng lặp lại cho đến khi lời hứa mà chúng tôi đang chờ giải quyết. Bạn cũng có thể sử dụng trong khi hoặc làm .. trong khi hoặc cho các vòng lặp với cấu trúc tương tự này. and the loop stops the iteration until the promise we're awaiting resolves. You could also use while or do.. while or for loops too with this same structure.

Làm thế nào để bạn chờ đợi một vòng lặp trong Python?

Làm thế nào để trì hoãn một vòng python..
1 - Ngủ.Hàm giấc ngủ từ mô -đun thời gian của Python tạm dừng việc thực hiện Python theo số giây được nhập.....
2 - tính toán giấc ngủ.Để làm điều này, chúng tôi tính toán thời gian vòng lặp nên ngủ trong bao lâu.....
3 - Trình lập lịch nhiệm vụ ..

Điều gì xảy ra nếu bạn sử dụng chờ đợi bên trong một vòng lặp và các lựa chọn thay thế là gì?

Khi đánh giá cho vòng lặp, chúng tôi đã chờ đợi lời hứa bên trong hàm Async, việc thực hiện sẽ tạm dừng cho đến khi lời hứa đang chờ đợi được giải quyết.Vì vậy, bạn có thể nghĩ rằng các tệp được đọc từng cái một theo thứ tự xác định.Đôi khi, chúng tôi thực sự cần các hàm Async được thực thi theo thứ tự tuần tự.the execution will pause until the await promise is settled. So, you can think of that the files are read one by one in a determined order. Sometimes, we really need the the async functions to be executed in a sequential order.

Chờ đợi có khối Python không?

Trong Python, chúng ta cần một từ khóa đang chờ đợi trước mỗi đối tượng Coroutine để được gọi bởi vòng lặp sự kiện.Nhưng khi chúng tôi chờ đợi, nó làm cho cuộc gọi chặn.Theo sau đó, chúng ta kết thúc việc làm điều tương tự như chúng ta làm trong thời trang chặn.when we put await , it makes the call blocking. It follows that we end up doing the same thing as we do in the blocking fashion.