2016-01-30 2 views
1

Работая над созданием основного текстового приключения в виде «Колоссальной пещерной приключения», «Зорка» и т. Д., Я столкнулся с проблемой с моими зомби и скелетами, которые, по-видимому, редактируют друг друга ,Подклассы Python, видимо редактируя друг друга

class Entity(object): 
    def __init__(self,name,hp,strength,defense,armor=False,weapon=Fist(),actions=["Attack","Block"]): 
     self.name = name 
     self.hp = self.maxhp = hp 
     self.strength = strength 
     self.default_defense = self.defense = defense 
     self.armor = armor 
     self.weapon = weapon 
     self.initiative = 0 
     self.actions = actions 

    def attack(self,target): 
     #An attack action 
    def block(self): 
     #A block action 
    def update(self): 
     #Updating the entity 

class Zombie(Entity): 
    def __init__(self): 
     Entity.__init__(self,"Zombie",random.randint(13,20),4,5,Leather()) 
     print self.actions #Printing the actions in order to try to fix this issue 
     self.actions.remove("Block") 
     print self.actions #Printing the actions in order to try to fix this issue 

class Skeleton(Entity): 
    def __init__(self): 
     Entity.__init__(self,"Skeleton",random.randint(16,23),6,5,False,Bow(999)) 
     print self.actions #Printing the actions in order to try to fix this issue 
     self.actions.remove("Block") 
     print self.actions #Printing the actions in order to try to fix this issue 

monsters = [Zombie(),Skeleton()] 

Когда код запускается, он возвращает

['Attack','Block'] 
['Attack'] 
['Attack'] 
#Error message 

ошибка говорит, что 'Block' не в костяка self.actions удалить, но, насколько я понимаю, идет, 'Block' должен быть там когда вызывается Entity.__init__. Если я переключу Zombie() и Skeleton() в monsters, проблема все равно будет, поэтому проблема заключается в том, что первый подкласс удаляет запись из обоих подклассов.

Я новичок в подклассах, поэтому очень вероятно, что проблема заключается в моем ограниченном понимании того, как они работают. Это предполагаемое поведение? Если да, то как мне получить поведение, которое я ищу?

+0

У меня нет голосов, но см. Http://stackoverflow.com/q/1132941/3001761 – jonrsharpe

+0

@jonrsharpe Очень полезно. Я ценю возможность понять проблему, а не просто ее исправление. –

ответ

1

Аргумент значения по умолчанию для __init__ оценивается только один раз. Итак, если вы не дадите что-нибудь еще для actions, каждый экземпляр Entity будет ссылаться на тот же список. И когда вы удаляете из этого списка в одном экземпляре, также изменяется список в других экземплярах.

Чтобы предотвратить это, попробуйте следующее:

class Entity: 
    def __init__(self, ... actions=None, ...): 
    ... 
    if actions is None: 
     self.actions = ["Attack", "Block"] 
    else: 
     self.actions = actions 

Затем actions список создается для каждого экземпляра.

0

Проблема заключается в том, что вы используете список в качестве аргумента по умолчанию для actions в __init__ из Entity.

В каждом из ваших подклассов содержится ссылка на исходный список ["Attack", "Block"]. Всякий раз, когда вы его изменяете, исходный список обновляется, что, вероятно, не то, что вы ожидали.

Чтобы избежать такой ошибки, используйте неизменяемые типы в качестве аргументов по умолчанию, например. tuple вместо list.

Смежные вопросы