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
相关产品推荐
相关产品推荐

