我在哪里搞乱跟踪派系联盟?

时间:2016-01-15 01:15:10

标签: python list self

我有一个模拟王国和其他群体的程序(在我的代码中称为“#f; factions'”)。

class Faction:
    def __init__(self, name, allies=[]):
        self.name = name
        self.allies = allies

    def is_ally_of(self, other_faction):
        if self in other_faction.allies:
            return True
        else:
            return False

    def become_ally(self, other_faction, both_ally=True):
        """ If both_ally is false, this does *not* also 
            add self to other_faction's ally list """
        if self.is_ally_of(other_faction):
            print("They're already allies!")
        else:
            self.allies.append(other_faction)
            if both_ally == True:
                other_faction.become_ally(self, False)

RezlaGovt = Faction("Kingdom of Rezla")
AzosGovt = Faction("Azos Ascendancy")

我希望能够调用派系的become_ally()方法将派系添加到盟友列表中,如下所示:

RezlaGovt.become_ally(AzosGovt) # Now AzosGovt should be in RezlaGovt.allies,
                                # and RezlaGovt in AzosGovt.allies

实际发生的是:

RezlaGovt.become_ally(AzosGovt)
# prints "They're already allies!"
# now AzosGovt is in the allies list of both AzosGovt and RezlaGovt, 
# but RezlaGovt isn't in any allies list at all.

每当我尝试调用become_ally()时,代码应该检查以确保它们不是盟友。这是不起作用的部分。每当我打电话给become_ally()时,它就会打印出#34;他们已经是盟友!",无论他们是否真的如此。

我也尝试使用if self in other_faction.allies:,但这也有同样的问题。

我强烈怀疑问题出在self,但我不知道谷歌的条款有哪些更多信息。

2 个答案:

答案 0 :(得分:2)

You can't use mutable arguments as the default argument to a function.

def __init__(self, name, allies=[]):

使用默认设置时,每次都是相同的 list,因此它们具有相同的allies;变异改变另一个因为它们实际上是相同的东西。

更改为:

def __init__(self, name, allies=None):
   if allies is None:
       allies = []

或者,无条件地复制allies参数(这样你就不会担心在课堂外存活并在课堂上变异的参考):

def __init__(self, name, allies=[]):
    self.allies = list(allies)  # Which also guarantees a tuple argument becomes list
                                # and non-iterable args are rejected

答案 1 :(得分:1)

更改此功能。

def is_ally_of(self, other_faction):
        if other_faction in self.allies:
            return True
        else:
            return False

检查您自己的数据,而不是传入的对象。

另外

def __init__(self, name, allies=[]):

等待发生的错误。您的allies列表将是所有实例之间共享的静态列表。而是使用

def __init__(self, name, allies=None):
        self.name = name
        self.allies = allies or []