我开始在 Pycord 库中制作 Python Discord 机器人。我想制作一个可以在多台服务器上运行的机器人,并且每台服务器都有不同的值。因此,为了做到这一点,我制作了一个字典,它将所有这些值存储在一个嵌套字典中。但是,当我尝试更改一个嵌套字典的值时,它会更改其他嵌套字典中的值。
server_ids = {} default_server_vals = {'beetle_game_started': False, 'beetle_message_id': None, 'beetle_message_channel': None, 'beetle_player_1': None, 'beetle_player_2': None, 'beetle_game_on': False, 'player1_list' : [], "player2_list":[]} @bot.event async def on_ready(): print('logged in') for i in bot.guilds: global server_ids global default_server_vals server_ids[str(i.id)] = default_server_vals print(server_ids) # Generate server IDS @bot.event async def on_guild_join(guild): server_ids[str(guild.id)] = default_server_vals @bot.slash_command(guild_ids=testing_servers, name="beetle", description="2 Player game") async def beetle(ctx): print(server_ids[str(ctx.guild.id)].get('beetle_game_on'), server_ids[str(ctx.guild.id)].get('beetle_game_started')) if server_ids[str(ctx.guild.id)].get('beetle_game_on') == False and server_ids[str(ctx.guild.id)].get('beetle_game_started') == False: await ctx.respond("Game starting! React to join.") game_start_embed = discord.Embed(title="React to join beetle game! (2 Players Only)", colour=discord.Colour.green()) game_start_embed.add_field(name="GAME RULES", value="""There are two players. There is one dice! The first player to finish the beetle drawing wins. Rolling a 1 – Body Rolling a 2 – Head Rolling a 3 – A leg Rolling a 4 – An eye Rolling a 5 – An antenna Rolling a 6 – The tail The first player to roll all 6 wins. However, the head and body must be drawn first to draw the other beetle parts.""") message = await ctx.send(embed=game_start_embed) await message.add_reaction("😎") print(ctx.guild.id) server_ids[str(ctx.guild.id)]['beetle_game_started'] = True print(server_ids) server_ids[str(ctx.guild.id)]['beetle_message_id'] = message.id server_ids[str(ctx.guild.id)]['beetle_message_channel'] = message.channel elif server_ids[str(ctx.guild.id)].get('beetle_game_started'): await ctx.respond("Someone already started a game! Try and join them.") else: await ctx.respond("There is already a beetle game playing!")
on_ready会获取机器人已处于的服务器 IDS,并将其放入全局server_ids变量中。然后将嵌套字典作为字典的服务器 ID 值。但是,当我尝试编辑嵌套字典的值(在 beetle 斜线命令中)时,它会更改所有其他嵌套值。
例如,当我尝试更改beetle_game_started的嵌套字典值时,它会打印以下内容:
{'912361242985918464': {'beetle_game_started': True, 'beetle_message_id': None, 'beetle_message_channel': None, 'beetle_player_1': None, 'beetle_player_2': None, 'beetle_game_on': False, 'player1_list': [], 'player2_list': []}, '938245167880753202': {'beetle_game_started': True, 'beetle_message_id': None, 'beetle_message_channel': None, 'beetle_player_1': None, 'beetle_player_2': None, 'beetle_game_on': False, 'player1_list': [], 'player2_list': []}}
它以某种方式改变了服务器 IDS 的两个嵌套字典的值(“beetle_game_started”的值)。我该如何在不改变其他字典值的情况下改变一个嵌套字典的值?
您看到这种行为的原因是因为 Python 中的字典是可变对象。
从提供的代码中提取相关部分
default_server_vals = {'beetle_game_started': False, 'beetle_message_id': None, 'beetle_message_channel': None, 'beetle_player_1': None, 'beetle_player_2': None, 'beetle_game_on': False, 'player1_list' : [], "player2_list":[]}
和
server_ids[str(i.id)] = default_server_vals
server_ids[str(i.id)] 赋值只是创建对单个字典的新引用。这就是为什么当你改变一个 id 的值时,你会看到所有其他 id 的变化。