Python 复制不实际复制而不引用

Python 复制不实际复制而不引用,python,Python,我很难理解为什么eMaxHP会随着当前的HP而不断变化,正如包含HP的怪物字典所指出的那样 import copy monsterDict = {'hp':5} class Battle(object): def __init__(self, monster): self.monster = monster def __str__(self): eMaxHP = copy.copy(self.monster['hp']) o

我很难理解为什么eMaxHP会随着当前的HP而不断变化,正如包含HP的怪物字典所指出的那样

import copy

monsterDict = {'hp':5}

class Battle(object):

    def __init__(self, monster):
        self.monster = monster

    def __str__(self):
        eMaxHP = copy.copy(self.monster['hp'])
        out = str(self.monster['hp'])  + "/" + str(eMaxHP)
        return out

    def damageEnemy(self):
        self.monster['hp'] -= 2

hi = Battle(monsterDict)
print(hi)
hi.damageEnemy()
print(hi)
最后怪物的生命值打印为12/12,如果你造成了18点伤害,它应该是12/30


我能做什么?

你的设计错了。你不会在任何地方保持怪物的最大生命值。当你调用
damage敌军
时,你只改变存放它的位置。在
\uuuu str\uuuu
中创建副本没有帮助-是的,您正在复制值,但在错误的位置执行

我想澄清一下:

  • 最初,您有
    hp.monster=monsterDict={“hp”:5}
    。只有一个dict实例,全局
    monsterDict
    变量和
    hp.monster
    属性都引用它
  • 当您调用
    print
    时,您创建了此dict的一个副本,使用它来打印“5/5”,但在方法退出时您放弃了该副本(它只是
    \uuu str\uu
    方法中的一个局部变量)
  • 当您调用
    damage敌方
    时,将减小此值。但是你这里只有一个dict,你要更新它。此时,任何地方都没有
    {“hp”:5}
    的dict
  • 因此,当您的
    print
    语句再次调用
    \uuu str\uuu
    时,唯一存在的是一个带有
    {“hp”:3}
    的dict。这就是它打印“3/3”的原因
  • 你可以这样做:

    ...
    class Battle(object):
        def __init__(self, monster):
            self.monster = monster
            self.initial_monster = copy.copy(monster)
    
        def __str__(self):
            return "{}/{}".format(self.monster["hp"], self.initial_monster["hp"])
        ...
    
    (如果不调用
    copy.copy
    而只分配
    self.initial\u monster=monster
    ,请务必检查会发生什么情况。如果不调用
    copy
    ,您将不会有两个dict实例,而只有一个实例被多次引用。)

    或者你可以制作一个怪物类,它保存两个值,我相信这更有意义。下面是我将如何做到这一点的草图:

    class Monster(object):
        def __init__(self, hp):
            self.hp = hp
            self.max_hp = hp
    
        def damage(self, hp):
            self.hp -= hp
            return self.hp
    
        def __str__(self):
            return "{}/{}".format(self.monster.hp, self.monster.max_hp)
    
    class Battle(object):
        def __init__(self, monster):
            self.monster = monster
    
        def __str__(self):
            return str(self.monster)
    
        def damage_enemy(self, hp=2):
            self.monster.damage(hp)
    
    battle = Battle(Monster(18))
    print(battle)
    for _ in range(0, 5):
        battle.damage_enemy()
        print(battle)
    

    谁该怎么猜字典里有什么?您需要提供一个足以演示问题的代码示例(但是,不要包含完整的解决方案——去掉不相关的部分);请阅读并遵循张贴指南。特别是,我们应该能够将您发布的代码粘贴到一个文件中,用Python运行它,并重现您的问题。@AlexRosenbach肯定没有您声称的那么简单。Python中的数字不是引用,因此您描述的行为是不可能的。贴一张!这样想吧,你的代码中有一些错误,但是如果没有你的代码,我们无法知道这是什么。打印出来,让我们看看!顺便说一句,这里是一个运行可验证的代码示例。。。至少我所知道的。它没有失败。如果你可以写这样的东西,但像你的代码一样失败,那么我们就有好的东西可以利用。