Hướng dẫn call async function from non async python - gọi hàm không đồng bộ từ python không đồng bộ

Vì vậy, tôi bị khóa vào một trình thông dịch Python 3.6.2 theo ứng dụng máy tính để bàn của tôi.

Điều tôi muốn là gọi hàm Async từ phương thức hoặc hàm được đồng bộ hóa.

Khi gọi chức năng Python từ ứng dụng máy tính để bàn, nó phải là một hàm bình thường không thể chờ đợi.

Từ ứng dụng máy tính để bàn, tôi có thể gửi một danh sách các URL và điều tôi muốn là gửi lại phản hồi từ mỗi URL trong một vấn đề không đồng bộ.

Đây là lần thử của tôi, tôi đã đánh dấu cú pháp mà tôi không biết cách bỏ qua.

import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]
timeout = 10

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        -> SyntaxError: newfeature = await main[urls_and_coords]
        self.pyoutput[newfeature]
        
    def close[self]:
       pass 

async def main[urls]:
    loop = asyncio.get_event_loop[]
    async with aiohttp.ClientSession[loop=loop] as session:
        feature = loop.run_until_complete[fetch_all[session, urls, loop]]
        return feature
        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            newFeature = fmeobjects.FMEFeature[]
            response_data = await response
            newFeature.setAttribute['response', response_data]
            newFeature.setAttribute['_xmin',url[1]]
            newFeature.setAttribute['_xmax',url[2]]
            newFeature.setAttribute['_ymin',url[3]]
            newFeature.setAttribute['_ymax',url[4]]
            return newFeature

Tôi đã thử thực hiện những thay đổi này:

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        

Nhưng bây giờ tôi kết thúc với lỗi này:

Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression

cloudfit-public-docs

Trong các phần trước của loạt bài này trên Python Asyncio, tôi đã giới thiệu cho bạn các khái niệm cơ bản, cú pháp cơ bản, một vài tính năng tiên tiến hơn và một số thư viện hữu ích. Trong phần này, tôi dự định đi sâu vào các chi tiết của các giao diện, bạn cũng có thể thấy mình cần sử dụng nếu bạn cần kết hợp mã đồng bộ và không đồng bộ trong cùng một dự án. Đây là điều mà chúng tôi đã bắt gặp nhiều lần trong dự án CloudFit của BBC R & D,, đặc biệt là khi sử dụng các thư viện hiện có chưa hỗ trợ trực tiếp với Asyncio.

Một điều bạn có thể làm, và một điều bạn thực sự không nên

Bạn có thể chạy mã Async trừ khi bạn có một vòng lặp sự kiện để chạy nó [mà không thực hiện một số công việc đặc biệt liên quan đến một đối tượng giả mạo là một vòng lặp sự kiện]. Vì vậy, chờ đợi các coroutines không đồng bộ trong một chương trình không có vòng lặp sự kiện đang chạy có nghĩa là bạn cần bắt đầu một vòng lặp sự kiện. May mắn thay, điều này không xuất hiện nhiều.

Ngược lại, bạn hoàn toàn có thể gọi mã không phải là ASYNC từ mã async, trên thực tế, nó rất dễ thực hiện. Nhưng nếu một cuộc gọi phương thức/chức năng có thể khối khối [tức là mất nhiều thời gian trước khi nó trở lại] thì bạn thực sự không nên.

Vấn đề với điều này có thể được nhìn thấy gọn gàng trong mã sau:

import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]

Khi mã này được chạy, đầu ra trông giống như thế này:

Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s

Như bạn có thể thấy, quầy đã tạm dừng trong suốt thời gian thực hiện yêu cầu HTTP. Điều này là do cuộc gọi requests.get là một cuộc gọi IO đồng bộ thông thường và không trả lại cho đến khi yêu cầu HTTP được hoàn thành. Vì nó không phải là mã không đồng bộ, vòng lặp sự kiện không thể làm gì để làm gián đoạn nó để cho các tác vụ khác chạy, và do đó, nó chặn vòng lặp sự kiện miễn là nó chạy.

Đương nhiên đây là một vấn đề.

Lưu ý: Cũng như đồng bộ [ví dụ: chặn] io có một loại phương thức Python khác có thể dễ dàng chặn vòng lặp sự kiện nếu bạn chạy chúng từ các quy trình Async Code: CPU-liên kết. Một quy trình ràng buộc CPU là bất kỳ đoạn mã nào thực hiện nhiều tính toán, hoặc nếu không thì chiếm giữ tất cả thời gian trên CPU trong khi nó chạy trong một khoảng thời gian dài. Một số ví dụ tốt về các quy trình ràng buộc CPU sẽ là đào tạo một mạng lưới thần kinh, nén một video thô thành H.264 hoặc thực hiện một loạt các biến đổi Fourier trên một bộ dữ liệu lớn. As well as synchronous [ie. blocking] IO there’s another class of Python methods which can easily block the event loop if you run them from async code: CPU-bound processes. A CPU-bound process is any piece of code which performs a lot of calculations, or otherwise occupies all the time on the CPU whilst it is running for an extended period of time. Some good examples of CPU bound processes would be training a neural network, compressing a raw video to H.264, or performing a series of fourier transforms on a large data set.

Có một số kỹ thuật bạn có thể sử dụng để giảm thiểu, và trong một số trường hợp hoàn toàn loại bỏ, tuy nhiên, vấn đề này.

Người thực thi và đa luồng

Asyncio về cơ bản là một công nghệ duy nhất. Mỗi vòng lặp sự kiện chạy trên một luồng duy nhất và ghép kênh thời gian chạy của luồng giữa các tác vụ khác nhau. Đây có thể là một mô hình hoạt động rất hiệu quả khi bạn có một nhiệm vụ ràng buộc IO được thực hiện bằng thư viện IO Asyncio-Aware. Đáng buồn thay, không phải tất cả các nhiệm vụ đều bị ràng buộc và tất cả các thư viện đều hỗ trợ Asyncio.

Đây là nơi đa luồng xuất hiện. Chỉ vì vòng lặp sự kiện của bạn chạy trên một luồng và ghép kênh sử dụng của nó không có nghĩa là chương trình của bạn có thể cũng có các luồng khác chạy cùng một lúc. Trên thực tế, nó rất hữu ích khi có sẵn một nhóm các chủ đề để bạn có thể gửi công việc chặn dài cho họ và cho phép những cuộc gọi chặn dài đến mỗi người chiếm một chủ đề của riêng họ trong khi họ chạy.

Vì đây là một mẫu hữu ích, nên không có gì ngạc nhiên khi thư viện Asyncio cung cấp một cách dễ dàng để làm điều này, sử dụng phương thức Loop Loop Loop ____ ____10. Do đó:

import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    def send_request[]:
        print["Sending HTTP request"]
        r = requests.get['//example.com']
        print[f"Got HTTP response with status {r.status_code}"]

    await asyncio.get_event_loop[].run_in_executor[send_request]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]

tạo ra đầu ra như thế này:

Started counter
Sending HTTP request
0: Was asleep for 0.0016489028930664062s
1: Was asleep for 0.0019485950469970703s
2: Was asleep for 0.0011708736419677734s
3: Was asleep for 0.00118255615234375s
4: Was asleep for 0.001283884048461914s
5: Was asleep for 0.001234292984008789s
6: Was asleep for 0.0011649131774902344s
7: Was asleep for 0.0012319087982177734s
8: Was asleep for 0.001219034194946289s
9: Was asleep for 0.001234292984008789s
Got HTTP response with status 200

Và như bạn có thể thấy lần này, bộ đếm không bị chặn bởi yêu cầu HTTP.

Vậy nó hoạt động như thế nào? Phương pháp

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 có hai hoặc nhiều đối số và trả về một tương lai. Đối số đầu tiên có thể được sử dụng để chỉ định nhóm chủ đề hoặc nhóm xử lý để sử dụng để chạy mã, nhưng nếu bạn đặt nó thành
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
2 thì nó sẽ sử dụng nhóm luồng mặc định thuộc sở hữu của vòng lặp sự kiện và điều này hầu như luôn luôn là bạn muốn gì. Tham số thứ hai là một cuộc gọi đồng bộ sẽ được chạy trong một luồng. Bất kỳ tham số nào được truyền qua cho người được gọi khi nó được gọi.

Tương lai được trả lại sẽ được đánh dấu là thực hiện khi Callable có thể gọi được cung cấp đã hoàn tất việc thực hiện trên luồng của nó. Nếu nó trả lại một giá trị sẽ được lưu trữ trong tương lai là kết quả, nếu nó nêu ra một ngoại lệ sẽ được lưu trữ trong tương lai như là ngoại lệ của nó. Điều này có nghĩa là đối với nhiều mục đích, bạn có thể đối xử với tương lai được trả lại bởi

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 rất giống với tương lai được trả lại bởi
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
4, nhưng với kiến ​​thức rằng các nhiệm vụ được tạo ra với
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
4 sẽ được ghép nối trên luồng của vòng lặp sự kiện, trong khi các nhiệm vụ được tạo bởi
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 sẽ được chạy Trên một chủ đề khác hoàn toàn, và sẽ bắt đầu thực hiện gần như ngay lập tức.

Kết thúc các cuộc gọi chặn để chạy trên các chủ đề khác bằng cách sử dụng

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 có lẽ là cách đơn giản nhất và dễ nhất để sử dụng các thư viện không dành cho việc sử dụng Asyncio khi viết chương trình Asyncio. Chắc chắn có những cạm bẫy tiềm năng [đặc biệt là nếu thư viện cơ bản không được đảm bảo an toàn], nhưng trên toàn bộ mã sẽ sử dụng kỹ thuật này và thậm chí bạn có thể sử dụng nó để tạo ra các giấy gói giống như asyncio xung quanh mã đồng bộ trong một Nhiều hoàn cảnh khác nhau. Nó đặc biệt hữu ích cho mã ràng buộc CPU.

Tuy nhiên, có một số kỹ thuật khác mà bạn cũng có thể hưởng lợi từ việc có trong hộp công cụ của mình, mặc dù chúng có khả năng được sử dụng ít thường xuyên hơn.

Lưu ý: Một số phiên bản của Python trong quá khứ đã chú thích sai

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 là một phương pháp coroutine. Điều này chưa bao giờ thực sự là trường hợp, và tất cả các triển khai thực tế của nó luôn là các phương pháp trả lại tương lai. Kể từ tháng 8 năm 2020, lỗi này đã được sửa trong thư viện tiêu chuẩn Python và được đánh máy, nhưng nếu bạn có phiên bản cũ hơn, bạn có thể thấy các chú thích/tài liệu loại không chính xác. Some versions of Python have in the past erroneously annotated
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0 as being a coroutine method. This has never actually been the case, and all actual implementations of it have always been methods that returned futures. As of August 2020 this error has been corrected in the Python standard library and in typeshed, but if you have older versions you may see incorrect type annotations/documentation.

Còn khóa phiên dịch toàn cầu thì sao?

Bạn có thể đã nghe nói về khóa phiên dịch toàn cầu của Python, và làm thế nào nó ngăn Python thực sự chạy mã đa luồng thích hợp theo kiểu song song. Điều này tương tác với

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
0, nhưng không tệ như lần đầu tiên xuất hiện.

Thuốc phiên dịch viên thông dịch viên Python là một loại mutex luôn được giữ bởi bất kỳ chủ đề nào hiện đang diễn giải các hướng dẫn Python trong một quy trình duy nhất. Kết quả là, nó thường không thể có hai luồng Python thực sự chạy mã Python đồng thời, mặc dù chúng có thể chuyển qua lại thường xuyên như giữa các hướng dẫn riêng lẻ.

Tuy nhiên, nếu một phương thức Python gọi mã gốc cho một mục đích nào đó thì Gil thường sẽ được phát hành. Do đó, nhiều luồng có thể chạy đồng thời nếu tất cả trừ một trong số chúng hiện đang chạy mã gốc.

Mã gốc thực hiện chặn IO trong Python phát hành GIL trong thời gian chặn của nó; Điều này có nghĩa là các tác vụ gắn IO bằng cách sử dụng chặn IO không khóa các luồng python khác trong khi chúng chặn.

Đối với các nhiệm vụ ràng buộc CPU, điều này có thể là một vấn đề nhiều hơn. Nhiều thư viện để thực hiện các hoạt động ràng buộc CPU gọi mã gốc để thực hiện xử lý nặng của chúng và phát hành GIL để các luồng khác sẽ không bị chặn. Tuy nhiên, nếu bạn cần chạy một tác vụ ràng buộc CPU được viết bằng Python thuần túy trong nền trong khi mã khác của bạn đang chạy thì các vấn đề có thể phát sinh. Các nhiệm vụ trong các luồng khác sẽ chạy chậm hơn, trải qua các tạm dừng thường xuyên khi trình thông dịch chuyển qua lại giữa các luồng.

Để làm việc xung quanh điều này, bạn có thể xây dựng một đối tượng của lớp

Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
0 và chuyển nó dưới dạng tham số đầu tiên của ____10, thay vì
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
2. Điều này sẽ khiến mã của bạn được chạy không phải trong một chủ đề khác, mà trong một quá trình khác hoàn toàn, và do đó Gil sẽ không được chia sẻ.

Đi theo một cách khác với
Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
3

Thỉnh thoảng, bạn có thể đang trong tình huống chạy mã đồng bộ trên luồng riêng của nó, cần gọi mã không đồng bộ trên luồng vòng lặp sự kiện. Trong trường hợp cụ thể này, vòng lặp sự kiện cung cấp một phương pháp đồng bộ

Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
3 có thể được sử dụng để làm những gì bạn muốn.

Cảnh báo: Kỹ thuật này chỉ hữu ích khi bạn ở trong một phương pháp đồng bộ đang chạy trên một luồng nhưng bạn biết rằng cũng có một vòng lặp sự kiện chạy trên một luồng khác. Bạn có thể sử dụng nó nếu phương pháp đồng bộ mà bạn đang chạy trên chuỗi vòng lặp sự kiện và bạn có thể sử dụng nó nếu không có vòng lặp sự kiện nào chạy. This technique is only useful when you are inside a synchronous method which is running on one thread but you know that there is also an event loop running on another thread. You can’t use it if the synchronous method you are in is running on the event loop’s thread, and you can’t use it if no event loop is running.

Phương pháp

Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
3 có hai tham số. Đầu tiên phải là một đối tượng coroutine [không phải là phương pháp coroutine có thể gọi được, tương lai hoặc bất cứ điều gì khác, chỉ là một đối tượng coroutine] và thứ hai phải là chính đối tượng vòng lặp sự kiện.

Cuộc gọi tạo ra một nhiệm vụ mới [sử dụng

import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
4] kết thúc coroutine đã cho. Sau đó, nó kết thúc nó bên trong một đối tượng của lớp
Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
7 khá giống với đối tượng
Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
8, nhưng dự định sử dụng trong các môi trường đa luồng.

Đối tượng được trả lại này có các phương pháp

Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
9,
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
0 và
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
1 giống như tương lai mà chúng tôi đã thảo luận trước đây, tuy nhiên
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
0 và
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
1 hoạt động tinh tế khác nhau. Cụ thể nếu được gọi khi tương lai chưa được thực hiện, họ không nêu ra một ngoại lệ. Thay vào đó, họ chặn luồng hiện tại và không quay lại cho đến khi tương lai hoàn thành. Theo nhiều cách, bạn có thể nghĩ về một cuộc gọi đến
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
4 trên
Python Exception : object ClientResponse can't be used in 'await' 
expression
Traceback [most recent call last]:
  File "", line 20, in input
  File "asyncio\base_events.py", line 467, in run_until_complete
  File "", line 29, in main
  File "", line 33, in fetch_all
  File "", line 41, in fetch
TypeError: object ClientResponse can't be used in 'await' expression
7 là tương tự như sử dụng tương lai Asyncio trong một tuyên bố
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
6.

Sử dụng IO không chặn và bỏ phiếu định kỳ

Đôi khi, một thư viện sẽ cung cấp một giao diện cho phép IO không chặn IO. Điều đó có nghĩa là thay vì gọi đến

import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
7 chặn cho đến khi có một số dữ liệu để đọc, có thể gọi nó với các tham số đặt nó ở chế độ không chặn, để cuộc gọi
import requests
import asyncio
import time

async def counter[]:
    now = time.time[]
    print["Started counter"]
    for i in range[0, 10]:
        last = now
        await asyncio.sleep[0.001]
        now = time.time[]
        print[f"{i}: Was asleep for {now - last}s"]

async def main[]:
    t = asyncio.get_event_loop[].create_task[counter[]]

    await asyncio.sleep[0]

    print["Sending HTTP request"]
    r = requests.get['//example.com']
    print[f"Got HTTP response with status {r.status_code}"]

    await t

asyncio.get_event_loop[].run_until_complete[main[]]
8 sẽ luôn quay lại ngay lập tức, nhưng nếu có không có dữ liệu nào có sẵn để đọc nó sẽ chỉ ra điều này theo một số thời trang [chẳng hạn như nâng cao ngoại lệ hoặc trả lại
import fme
import fmeobjects
import asyncio
import aiohttp
import async_timeout
logger = fmeobjects.FMELogFile[]

class FeatureProcessor[object]:
    def __init__[self]:
        pass
    def input[self, feature]:
        urls_and_coords = zip[feature.getAttribute['_list{}._wms'],\
        feature.getAttribute['_list{}._xmin'],\
        feature.getAttribute['_list{}._ymin'],\
        feature.getAttribute['_list{}._xmax'],\
        feature.getAttribute['_list{}._ymax']]
        loop = asyncio.get_event_loop[]
        result = loop.run_until_complete[main[loop, urls_and_coords]]
        #feature.setAttribute['result',result]
        self.pyoutput[feature]
        
    def close[self]:
       pass 

async def main[loop, urls]:
    async with aiohttp.ClientSession[loop=loop] as session:
        return await fetch_all[session, urls, loop]

        
async def fetch_all[session, urls, loop]:
    results = await asyncio.gather[*[loop.create_task[fetch[session, url]] for url in urls]]
    return results
    

async def fetch[session, url]:
    with async_timeout.timeout[10]:
        async with session.get[url[0]] as response:
            #newFeature = fmeobjects.FMEFeature[]
            response = await response
            #newFeature.setAttribute['response', response_data]
            #newFeature.setAttribute['_xmin',url[1]]
            #newFeature.setAttribute['_xmax',url[2]]
            #newFeature.setAttribute['_ymin',url[3]]
            #newFeature.setAttribute['_ymax',url[4]]
            return response, url[1], url[2], url[3], url[4]


        
2]. Đây là trường hợp bạn có thể dễ dàng tạo một số mã như sau:

async def read_async[data_source]:
    while True:
        r = data_source.read[block=False]
        if r is not None:
            return r
        else:
            await asyncio.sleep[0.01]

Sẽ hoạt động như một phiên bản nhanh chóng và bẩn thỉu của một coroutine đọc không đồng bộ cho data_source. Cụ thể khi được chờ đợi, nó sẽ định kỳ kiểm tra dữ liệu có sẵn, trả lại nếu có một số, nhưng nếu không sẽ ngủ cho đến khi kiểm tra tiếp theo.

Đây không phải là cách hiệu quả nhất để sử dụng giao diện đồng bộ và làm cho nó không đồng bộ, nhưng nó có thể đơn giản hơn các tùy chọn khác trong một số trường hợp, và có lẽ nó có thể đủ hiệu quả.

Xem mô tả tập tin

Tùy chọn cuối cùng của bạn để sử dụng các thói quen liên kết IO đồng bộ theo kiểu không đồng bộ là sử dụng các cơ chế cấp thấp được cung cấp bởi hệ điều hành và vòng lặp sự kiện cho mục đích này. Đây là những gì các nhà văn của các thư viện Asyncio thường sẽ làm, và có khả năng là kết quả hiệu quả nhất, mặc dù trong nhiều trường hợp, khó khăn nhất và phức tạp nhất để viết.

Nếu thư viện cơ bản của bạn có thể cung cấp một mô tả tệp của Google [một hệ điều hành được cung cấp đối tượng xác định tài nguyên có thể chờ đợi] thì bạn có thể sử dụng điều đó bằng cách sử dụng các phương thức Loop Loop:

Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
0 và
Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
1. Hai phương thức này cho phép bạn chỉ định một phương thức gọi lại đồng bộ sẽ được gọi là mỗi khi một mô tả tệp cụ thể cho thấy rằng nó có sẵn để đọc hoặc viết, tương ứng. Tùy thuộc vào cơ chế cơ bản để truyền dữ liệu là gì, có thể là cuộc gọi lại sẽ bắn mặc dù chưa có đủ dữ liệu để đọc [hoặc đủ không gian cho người viết], vì vậy bạn cần phải kiểm tra mỗi khi nó gọi. Nhưng dù sao điều này cho phép tạo ra một phiên bản cải tiến đáng kể của
Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
2 Coroutine từ ví dụ trước:

async def read_async[data_source]:
    loop = asyncio.get_running_loop[]
    fd = data_source.get_fd[]
    fut = loop.create_future[]

    def __check_for_read[]:
        try:
            r = data_source.read[block=False]
        except Exception as e:
            loop.remove_reader[fd]
            fut.set_exception[e]
        else:
            if r is not None:
                loop.remove_reader[fd]
                fut.set_result[r]

    loop.add_reader[fd, __check_for_read]
    return await fut

Phiên bản này của coroutine không còn ngủ theo định kỳ, thay vào đó nó tạo ra một tương lai, sau đó thêm một cuộc gọi lại vào vòng lặp sự kiện sẽ được gọi bất cứ khi nào có dữ liệu về bộ mô tả tệp cơ bản sẽ được đọc, và sau đó chờ đợi tương lai. Mỗi lần gọi lại, nó sẽ cố gắng đọc dữ liệu từ nguồn dữ liệu và nếu nó có thể thiết lập tương lai để thực hiện với dữ liệu như kết quả của nó, nếu nó không thể làm được gì. Nếu một ngoại lệ được nâng lên bởi cuộc gọi để đọc nguồn dữ liệu thì ngoại lệ này cũng được truyền đến tương lai.

Nếu bạn có thể quản lý nó, đây có thể là một cách tốt hơn để cung cấp một trình bao bọc không đồng bộ xung quanh quy trình liên kết IO đồng bộ mô tả để làm việc với.

Lưu ý: Thư viện Asyncio cũng cung cấp các công cụ cụ thể hơn để xử lý các ổ cắm mạng sử dụng các lớp

Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
3 và
Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
4. Nếu bạn đang viết một thư viện sẽ cung cấp quyền truy cập ASYNC vào một giao thức mạng cụ thể hoặc chuyển đổi một thư viện hiện có như vậy từ chức năng đồng bộ sang không đồng bộ thì những điều này sẽ cực kỳ hữu ích cho bạn. Nếu không, tôi sẽ khuyên bạn nên điều khiển rõ ràng về họ.
The asyncio library also provides more specific tools for dealing with network sockets making use of
Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
3 and
Started counter
Sending HTTP request
Got HTTP response with status 200
0: Was asleep for 0.019963502883911133s
1: Was asleep for 0.0012884140014648438s
2: Was asleep for 0.0012254714965820312s
3: Was asleep for 0.0011649131774902344s
4: Was asleep for 0.0011239051818847656s
5: Was asleep for 0.0012202262878417969s
6: Was asleep for 0.0012269020080566406s
7: Was asleep for 0.001184701919555664s
8: Was asleep for 0.0011556148529052734s
9: Was asleep for 0.00115203857421875s
4 classes. If you are writing a library which will provide async access to a specific network protocol or converting an existing such library from synchronous to asynchronous functioning then these will be extremely useful to you. Otherwise I would recommend steering clear of them.

Bản tóm tắt

Với tất cả mọi thứ trong phần này và các phần trước của loạt bài này, giờ đây bạn có thể viết mã sử dụng asyncio cho hầu hết các mục đích phát triển và cũng viết các trình bao bọc hữu ích để cho phép bạn tương tác với các thư viện không phải là asyncio mà bạn phải sử dụng . Tất cả trong tất cả tôi hy vọng đây là một loạt các bài báo, và đã giúp làm sáng tỏ phần Python này. Tôi chủ yếu dự định những bài viết này để trình bày những điều tôi ước tôi đã biết khi tôi bắt đầu sử dụng nó. Nhưng nếu bạn có bất kỳ đề xuất nào cho các chủ đề nên được bảo hiểm nhưng aren cảm thấy thoải mái để liên lạc.

Làm thế nào để bạn gọi chức năng async trong python?

Trong Asyncio Coroutine có thể được tạo bằng cách sử dụng từ khóa Async trước Def. Để chạy chức năng Async [Coroutine], bạn phải gọi nó bằng cách sử dụng vòng lặp sự kiện. Các vòng lặp sự kiện: Bạn có thể nghĩ về vòng lặp sự kiện là các chức năng để chạy các tác vụ và cuộc gọi lại không đồng bộ, thực hiện các hoạt động IO mạng và chạy các quy trình con.call it using an Event Loop. Event Loops: You can think of Event Loop as functions to run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses.

Làm thế nào để bạn gọi chức năng async mà không chờ đợi python?

Làm thế nào để tôi chạy Async mà không đang chờ đợi trong Python ?..
nhập khẩu asyncio ..
async def main []:.
in ['Xin chào'].
chờ đợi asyncio.Ngủ [1].
In ['Thế giới!'].
# Python 3.7+.

Tôi có thể chờ không

Vì vậy, đó là một quy tắc khá chắc chắn mà bạn không thể sử dụng đang chờ trong một hàm không phải là ASYNC.Bất cứ khi nào Asyncio quyết định nó có đủ tài nguyên mà nó gửi tin nhắn đó.you cannot use await in a non-async function. Whenever asyncio decides it has enough resources it sends that message.

Tôi có thể gọi hàm async bên trong hàm async không?

Async và chờ đợi bên trong hàm Async, bạn có thể sử dụng từ khóa đang chờ đợi trước khi gọi đến một hàm trả về lời hứa.Điều này làm cho mã chờ vào thời điểm đó cho đến khi lời hứa được giải quyết, tại thời điểm đó, giá trị hoàn thành của lời hứa được coi là giá trị trả lại hoặc giá trị bị từ chối được ném.you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Bài Viết Liên Quan

Chủ Đề