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

aiogram开发Telegram Bot时JSON写入冲突及__aenter__报错求解

报错根因
  • AttributeError: __aenter__ 报错触发原因:Python内置的open()是同步上下文管理器,未实现异步上下文协议要求的__aenter__、__aexit__方法,无法配合async with语法使用。
  • 原有逻辑的额外隐患:多用户并发触发写入时会产生竞态条件,出现写操作互相覆盖、JSON文件内容损坏的问题;同步IO直接运行在异步协程中还会阻塞事件循环,导致机器人暂时无法响应其他用户请求。
修复方案

前置依赖安装

先安装异步文件操作依赖:

pip install aiofiles

完整实现代码

核心逻辑两点:用aiofiles做非阻塞的异步文件读写,加全局异步锁让所有写请求排队执行,从根源避免并发冲突。

import json
import aiofiles
from asyncio import Lock
from aiogram import types
from aiogram.dispatcher import FSMContext

# 全局配置
DATA_SAVE_PATH = "D:/Code/data.json"
# 全局异步写入锁,同一时间仅允许一个协程执行文件写操作
file_write_lock = Lock()


async def load_abit_class(message: types.Message, state: FSMContext):
    async with state.proxy() as abit_data:
        abit_data['class'] = int(message.text)
        # 抢锁,锁释放前其他写入请求会等待
        async with file_write_lock:
            # 异步打开文件,不会阻塞事件循环
            async with aiofiles.open(DATA_SAVE_PATH, 'w', encoding='utf-8') as f:
                # 序列化为JSON字符串,指定ensure_ascii=False避免中文乱码
                json_content = json.dumps(abit_data, ensure_ascii=False, indent=2)
                await f.write(json_content)
    await state.finish()

补充说明

  • 如果你是多进程部署机器人(比如启动了多个服务worker),协程锁无法跨进程生效,需要替换为跨进程的文件锁,比如使用filelock库的AsyncFileLock实现。
  • 如果后续数据量变大、读写频率变高,建议直接替换为SQLite这类轻量嵌入式数据库,原生支持事务并发控制,不需要手动维护锁逻辑,稳定性远高于手动读写JSON文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:27:25