Python 3.x Python3/PyGame:Surfaces引用/处理(前标题:复制词典的奇怪行为)

Python 3.x Python3/PyGame:Surfaces引用/处理(前标题:复制词典的奇怪行为),python-3.x,pygame,surface,Python 3.x,Pygame,Surface,技术背景:WinXP系统上的Python 3.4+PyGame 1.9.2 重要 最初的标题是误导性的,因为它与Python字典的工作方式无关!这只是碰巧发生在一本字典上。我很快解释了这个问题,希望它对将来的人有用 有两个字典代表两个玩家的“棋盘”(这是一种战舰/海战的电脑游戏),包含位置元组(x,y)作为键,表面作为键的内容。一些用于澄清的伪代码: surface1 = pygame.Surface((w, h)).convert() surface1.fill(WATER_COLOUR)

技术背景:WinXP系统上的Python 3.4+PyGame 1.9.2

重要

最初的标题是误导性的,因为它与Python字典的工作方式无关!这只是碰巧发生在一本字典上。我很快解释了这个问题,希望它对将来的人有用

有两个字典代表两个玩家的“棋盘”(这是一种战舰/海战的电脑游戏),包含位置元组(x,y)作为键,表面作为键的内容。一些用于澄清的伪代码:

surface1 = pygame.Surface((w, h)).convert()
surface1.fill(WATER_COLOUR)

dict1 = {(x1, y1): surface1.copy(), (x2, y2): surface1.copy(), (x3, y3): surface1.copy()}
dict2 = dict1.copy()
在游戏过程中,玩家会点击显示屏,如果他们击中了一个有效的游戏区域,该区域将根据船只是否被击中而改变颜色

def clicked(mousepos, key):
    if active_player == 1:
        if mousepos_inside_enemy_ship_rectangle(mousepos):
            dict1[position_of_mouse].fill((255, 0, 0)) # Make it red
        else:
            dict1[position_of_mouse].fill((0, 0, 0)) # Make it black
令我惊讶的是,在这两本词典中,所有的正方形表面都会改变颜色!我最初认为,这是字典的问题,直到我发现,这是PyGame中曲面如何工作的问题

似乎所有surface1.copy()都引用了surface1的一个副本。也就是说:如果我改变了其中一个副本,所有其他副本看起来都一样,它们不是真的复制它,它们只是引用它

有两种解决方案:

  • 为每个状态创建一个曲面:一个用于“尚未点击”,一个用于“点击但未点击”,另一个用于“点击并点击”。然后将字典键更改为相应的曲面

  • 为字典中的每个关键点创建一个单独的曲面,然后分别用各自的颜色填充它们。这也行得通

  • 感谢所有试图解决这一问题的人,并对由此带来的麻烦表示歉意。。。这是一个完全不同的问题。我更新了标题和关键词,希望将来能帮助别人。我留下了旧的问题文本供参考。无论是谁添加了另一个字典问题的链接:请删除它,这不是关于字典,而是表面,谢谢



    旧问题文本留作参考

    我的脚本有一个函数
    f()
    返回字典:

    def f(data):
        d = {}
        for n in range(len(data)):
            d.update({n: data[n]})
        return d
    
    我需要两个字典以完全相同的数据开始,这样我就可以用不同的方式修改这些数据

    dict1 = f(data)
    dict2 = dict1.copy()
    
    令我惊讶的是,当我修改
    dict1
    时,
    dict2
    也会显示相同的更改!我以为复印件与原件是独立的——我误解了什么吗

    它肯定与
    .copy()
    方法有关。当我像这样更改代码时:

    dict1 = f(data)
    dict2 = f(data)
    
    我收到的正是我想要的,我可以对两本词典进行不同的修改,而不会相互干扰

    基本上这解决了我的问题,但它提出了一些问题。。。我是否误解了
    .copy()
    的作用?在这个Python版本中,这是一个普遍问题吗

    //编辑:

    为了澄清我所说的“修改”是什么意思:

    如果钥匙满足特定条件,则dict1中的某些钥匙数据会发生变化:

    for key in dict1:
        if key == meets_this_condition:
            dict1[key] = new_data
    
    在另一种方法中,我经常比较两个字典的内容,并根据它们的相同或不同调用某些函数

    for key in dict1:
        if dict1[key] == dict2[key]:
            do_something()
        else:
            do_something_else()
    
    谢谢你的见解


    Pat

    我会尝试使用deepcopy函数,比如

      dict2=copy.deepcopy(dict1);
    
    导入复制库


    我记得,复制做一个浅复制,这样它就只复制指针了。因此,如果您在某些情况下修改了一个,则副本也将更改。

    我更新了我的问题,谢谢您指出!多亏了你的努力,我才能找到错误发生的地方!我再次更新了我的问题,作为其他发现相同问题的人的参考。我认为这是公认的答案。它并没有精确地指向核心,但它把我推向了正确的方向。非常感谢你!整个问题都与PyGame如何处理其表面有关。请参阅更新的问题以获取更准确的信息。