You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为asyncio.create_task附加额外数据?附Python示例

为asyncio任务附加额外数据的优化方案

针对你提出的问题,这里提供几种无需修改原download_file函数职责的优化方案:

1. 用包装协程绑定关联数据

创建一个外层包装协程,负责调用原下载函数并同时返回关联的Foo对象,既保持原函数的单一职责,又能关联任务与数据:

import asyncio
from dataclasses import dataclass

@dataclass
class Foo:
    name: str
    url_to_download: str
    size: int

async def download_file(url: str):
    # 模拟下载逻辑
    return f"content from {url}"

# 新增包装协程,绑定Foo对象与下载任务
async def wrapped_download(foo_obj: Foo):
    download_result = await download_file(foo_obj.url_to_download)
    return foo_obj, download_result

objs = [Foo("file1", "http://example.com/file1", 1024), Foo("file2", "http://example.com/file2", 2048)]

tasks = [asyncio.create_task(wrapped_download(obj)) for obj in objs]

for task in asyncio.as_completed(tasks):
    foo, data = await task
    print(f"处理文件: {foo.name}, 下载内容: {data}")

2. 直接为Task对象附加自定义属性

asyncio的Task对象允许添加自定义属性,只需在创建任务后直接绑定Foo对象即可,无需修改任何协程函数:

import asyncio
from dataclasses import dataclass

@dataclass
class Foo:
    name: str
    url_to_download: str
    size: int

async def download_file(url: str):
    return f"content from {url}"

objs = [Foo("file1", "http://example.com/file1", 1024), Foo("file2", "http://example.com/file2", 2048)]

tasks = []
for obj in objs:
    task = asyncio.create_task(download_file(obj.url_to_download))
    # 直接为任务附加Foo对象属性
    task.associated_foo = obj
    tasks.append(task)

for task in asyncio.as_completed(tasks):
    data = await task
    foo = task.associated_foo
    print(f"处理文件: {foo.name}, 下载内容: {data}")

3. 用字典映射任务与Foo对象

通过外部字典建立任务到Foo对象的映射关系,完全解耦任务与关联数据:

import asyncio
from dataclasses import dataclass

@dataclass
class Foo:
    name: str
    url_to_download: str
    size: int

async def download_file(url: str):
    return f"content from {url}"

objs = [Foo("file1", "http://example.com/file1", 1024), Foo("file2", "http://example.com/file2", 2048)]

task_foo_map = {}
tasks = []
for obj in objs:
    task = asyncio.create_task(download_file(obj.url_to_download))
    task_foo_map[task] = obj
    tasks.append(task)

for task in asyncio.as_completed(tasks):
    data = await task
    foo = task_foo_map[task]
    print(f"处理文件: {foo.name}, 下载内容: {data}")

方案对比

  • 包装协程:符合单一职责原则,原下载函数无需改动,适合需要严格分离职责的场景。
  • 自定义任务属性:代码改动最小,实现最简洁,适合快速迭代的场景。
  • 字典映射:完全解耦任务与数据,避免修改任务对象本身,适合对任务对象有严格约束的场景。

内容的提问来源于stack exchange,提问作者tsybaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:16:12