添加后删除实例

2024-10-03 23:24:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用python学习OOP。我想知道如何创建军队,当我合并军队时,删除与指定军队合并的军队

class Army:
    def __init__(self, spear, sword, archer):
        self.composition = {'spear': spear, 'sword': sword, 'archer': archer}

    def __add__(self, other):
        for item in other.composition:
            self.composition[item] += other.composition[item]
        del other

然后在控制台中键入:

army1 = Army(10, 20, 30)
army2 = Army(30, 5, 0)
army1+army2

不删除army2。但是,如果我键入del army2,它会删除实例


Tags: self键入defitemoopothercompositiondel
3条回答

这不起作用的原因是del在一个原始名称上只会解除对象与该特定名称的绑定。如果对象在其他地方被引用,在本例中是由调用者中的army2引用的,那么对象继续存在del除了拒绝特定名称del-ed下的访问之外,没有任何效果

如果你一定要有这种行为,我建议你做两件事:

  1. 对于这种行为,不要使操作符过载+预计不会影响任何一个操作数,它应该生成一个全新的对象,并包含这两个操作数的总和/串联。虽然+=可以修改左侧操作数,但不应该修改右侧操作数。重载运算符时,通常的经验法则是“不”,然后是“好的,但前提是它遵守该运算符的预期语义”,这种情况肯定与++=的预期语义不匹配
  2. 现在我们已经决定使用一种方法,您可以通过移除另一支军队的内容从另一支军队中移除军队。例如:

    class Army:
        def __init__(self, spear, sword, archer):
            self.composition = {'spear': spear, 'sword': sword, 'archer': archer}
    
        def absorb_army(self, other):  # or transfer_troops or whatever
            '''Removes all the troops from other, combining them with the troops of self'''
            for item in other.composition:
                self.composition[item] += other.composition[item]
            other.composition.clear()  # Leaves other.composition empty
    
    army1 = Army(10, 20, 30)
    army2 = Army(30, 5, 0)
    army1.absorb_army(army2)
    # army2 still exists, but all the troops in it are gone, moved to army1
    

请注意,我编写的absorb_army可能会违反类的其他约束(因为类的所有元素都应该有composition包括'spear''sword''archer')。如果这是一个问题,不要clear它,只要重新分配所有键为零,例如:

        def absorb_army(self, other):
            for item in other.composition:
                self.composition[item] += other.composition[item]
                other.composition[item] = 0  # Zero after adding to self

del关键字删除的是引用(或名称),而不是对象本身。因为您是在函数内部使用del,所以只在函数中删除该引用。这就是为什么即使添加了army1+army2,您仍然能够访问army2

Python内置了垃圾收集功能,所以我不必担心手动删除变量,很可能最终会减慢速度

del other只会使“其他”名称停止存在,并引用您的第二支军队。仅此而已:此名称将消失,因为一旦退出此方法,它将消失

army2对象只有在引用它的所有名称都被删除并被垃圾收集后才会停止存在。在你的方法里你不能这么做

就让这第二支军队被遗忘吧

相关问题 更多 >