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

Asyncio队列添加字典元素出现循环覆盖重复问题求助

问题分析:异步分页API请求器队列元素被覆盖的原因

问题描述

实现了带有超时、队列和多工作进程的异步分页API请求器,设置3个工作进程消费队列元素。当请求结果为第1页且总页数大于1时,尝试修改已用参数的page值(从2到总页数)后放入队列:

if result['page'] < result['total_pages'] and result['page'] == 1:
    for page in range(2, result['total_pages']+1):
        request_kwargs['params']['page'] = page
        queue.put_nowait(request_kwargs)

但出现异常:每次循环都会覆盖队列中之前的元素,最终队列里全是最后一次循环设置的page值(比如第6次循环后,6个元素的page都是6)。而直接将page值放入队列时则正常:

if result['page'] < result['total_pages'] and result['page'] == 1:
    for page in range(2, result['total_pages']+1):
        queue.put_nowait(page)

问题根源

Python中字典是可变对象,你每次放入队列的request_kwargs都是同一个字典的引用,而非新的独立字典。队列里存储的只是指向这个字典的内存地址,后续循环中修改request_kwargs['params']['page']时,所有指向该字典的引用都会看到这个变化,导致之前放入队列的元素也被同步修改。

而直接放page值正常,是因为整数是不可变对象,每次放入队列的都是全新的整数实例,后续循环不会影响之前的元素。

解决方案

每次循环时创建request_kwargs的独立副本,再修改page值后放入队列。常用两种方式:

1. 深拷贝(适合复杂嵌套结构)

使用copy.deepcopy创建完全独立的字典副本:

import copy

if result['page'] < result['total_pages'] and result['page'] == 1:
    for page in range(2, result['total_pages']+1):
        new_request_kwargs = copy.deepcopy(request_kwargs)
        new_request_kwargs['params']['page'] = page
        queue.put_nowait(new_request_kwargs)

2. 手动浅拷贝(适合简单结构)

如果request_kwargs的结构不复杂,也可以逐层复制:

if result['page'] < result['total_pages'] and result['page'] == 1:
    for page in range(2, result['total_pages']+1):
        # 复制params字典
        new_params = request_kwargs['params'].copy()
        new_params['page'] = page
        # 构建新的请求参数字典
        new_request_kwargs = {
            'method': request_kwargs['method'],
            'url': request_kwargs['url'],
            'params': new_params
        }
        queue.put_nowait(new_request_kwargs)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:54:18