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

Discord.py命令改为,open触发AttributeError错误求助

问题

开发Discord经济机器人时,命令名用,create能正常运行,但改为,open后触发错误。

错误信息:

/home/runner/w/main.py:13: RuntimeWarning: coroutine 'Command.__call__' was never awaited
  with open('user_accounts.json', 'w') as f:
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
2024-02-20 23:51:22 ERROR    discord.ext.commands.bot Ignoring exception in command open
Traceback (most recent call last):
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 235, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/runner/w/main.py", line 33, in open
    save_accounts()
  File "/home/runner/w/main.py", line 13, in save_accounts
    with open('user_accounts.json', 'w') as f:
AttributeError: __enter__

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1029, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/home/runner/w/.pythonlibs/lib/python3.10/site-packages/discord/ext/commands/core.py", line 244, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: __enter__

当前代码:

def save_accounts():
    with open('user_accounts.json', 'w') as f:
        json.dump(user_accounts, f, indent=4)

try:
    with open('user_accounts.json', 'r') as f:
        user_accounts = json.load(f)
except FileNotFoundError:
    user_accounts = {}

@bot.event
async def on_ready():
    print(f'{bot.user.name} is online')

@bot.command()
async def open(ctx):
    user_id = str(ctx.author.id)
    if user_id not in user_accounts:
        user_accounts[user_id] = {'balance': 15}
        await ctx.send('Account created successfully!')
        save_accounts()
    else:
        await ctx.send('You already have an account.')
解决方案

问题根源

open是Python内置的文件打开函数,你把命令函数名设为open后,会覆盖全局作用域里的内置open函数。当save_accounts调用open()时,实际调用的是你定义的Discord命令协程对象,而协程不支持with语句需要的上下文管理器接口(缺少__enter__方法),所以抛出错误。

修复代码

给命令指定显示名称,同时修改内部函数名避免冲突:

def save_accounts():
    with open('user_accounts.json', 'w') as f:
        json.dump(user_accounts, f, indent=4)

try:
    with open('user_accounts.json', 'r') as f:
        user_accounts = json.load(f)
except FileNotFoundError:
    user_accounts = {}

@bot.event
async def on_ready():
    print(f'{bot.user.name} is online')

@bot.command(name="open")
async def open_account(ctx):
    user_id = str(ctx.author.id)
    if user_id not in user_accounts:
        user_accounts[user_id] = {'balance': 15}
        await ctx.send('Account created successfully!')
        save_accounts()
    else:
        await ctx.send('You already have an account.')

说明

  • @bot.command(name="open") 指定用户调用的命令名为,open
  • 内部函数名改为open_account,不会覆盖内置open函数
  • 这样save_accounts里的open()会正确调用内置的文件打开函数,恢复正常功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:22:44