Python open()创建Discord机器人黑名单文件失败,报FileNotFoundError求助
解决Discord机器人黑名单功能的FileNotFoundError问题
看起来你在开发Discord机器人的黑名单功能时遇到了文件创建的问题,我来帮你拆解错误原因并给出修复方案:
错误根源分析
你看到的FileNotFoundError并不是因为open()函数无法创建文件,而是因为你指定的存储目录不存在:
open()的w或x模式确实能自动创建不存在的文件,但前提是文件所在的上级目录已经存在。如果目录本身就没创建,Python就不知道该把文件放在哪里,自然会抛出这个错误。- 你代码里用了
os.path.expanduser("~/Blacklisted/{}.json"),但~/Blacklisted这个目录如果没提前手动创建,Python没办法自动帮你生成这个目录。
分步修复方案
1. 先创建目标目录
在打开文件之前,先检查并创建~/Blacklisted目录。用os.makedirs()就能轻松实现,加上exist_ok=True参数还能避免重复创建目录时的报错:
import os import json # 别忘了导入json模块 # 先获取目录路径 blacklist_dir = os.path.expanduser("~/Blacklisted") # 创建目录(不存在则创建,存在则跳过) os.makedirs(blacklist_dir, exist_ok=True)
2. 修正JSON写入的错误
你之前手动拼接JSON字符串的方式很容易出现语法问题(比如引号转义错误),正确的做法是先构造Python字典,再用json.dump()把字典序列化为标准JSON格式写入文件:
# 构造黑名单数据字典 blacklist_data = { user.id: { "userid": user.id, "reason": reason, "banned_by": ctx.message.author.id, "case_id": case_id, "active": "True" } } # 拼接完整文件路径 file_path = os.path.join(blacklist_dir, f"{ctx.message.author.id}.json") # 写入文件(用with语句自动关闭文件,更安全) with open(file_path, "w") as json_file: json.dump(blacklist_data, json_file, indent=4) # indent参数让JSON格式更易读
3. 额外注意事项
- 如果你之前写的是
/Blacklisted/(没有~),这是系统根目录下的文件夹,普通用户没有权限创建,所以一定要用~/Blacklisted指向当前运行用户的主目录下的文件夹。 - 确保机器人进程有创建目录和文件的权限,尤其是在Linux/macOS系统下,避免因为权限不足导致的写入失败。
完整修正后的add分支代码
@bot.command(pass_context=True) async def blacklist(ctx, removeoradd, user: discord.Member, *, reason): if ctx.message.author.id == developerID: if removeoradd == "add": case_id = "BL-" + id_generator(10, "1234567890") # 构造黑名单数据 blacklist_data = { user.id: { "userid": user.id, "reason": reason, "banned_by": ctx.message.author.id, "case_id": case_id, "active": "True" } } # 处理目录与文件 blacklist_dir = os.path.expanduser("~/Blacklisted") os.makedirs(blacklist_dir, exist_ok=True) file_path = os.path.join(blacklist_dir, f"{ctx.message.author.id}.json") # 写入JSON文件 with open(file_path, "w") as json_file: json.dump(blacklist_data, json_file, indent=4) # 发送管理员通知 embed = discord.Embed(title="Admin Control", description="Blacklisted:\n``{}/{}``".format(user.name, user.id)) embed.add_field(name="Reason", value=reason) embed.add_field(name="Case ID", value=case_id) embed.set_footer(text="v" + version + " | " + localtime) await bot.say(embed=embed) # 发送用户通知 embed = discord.Embed(title="You can no longer create a profile.", description="If you think this is a mistake do {}appeal <reason>".format(prefix)) embed.add_field(name="Reason", value=reason) embed.add_field(name="Case ID", value=case_id) embed.set_footer(text="v" + version + " | " + localtime) await bot.send_message(ctx.message.author, embed=embed) elif removeoradd == "remove": # 这里可以补充移除黑名单的逻辑,比如读取文件删除对应条目 pass else: embed=discord.Embed(title="An error occured", description="Invalid argument.\nInsert ``add`` or ``remove``.", color=0xc20000) await bot.say(embed=embed) else: embed=discord.Embed(title="An error occured", description="No permission.\nYou need to be a verified developer to do this.", color=0xc20000) await bot.say(embed=embed)
内容的提问来源于stack exchange,提问作者Novial
相关产品推荐
相关产品推荐

