2015-08-03 2 views
2

Относительно новый для ООП, просто возиться с попыткой создать класс NPC для игры, который должен генерировать разные экземпляры NPC на основе случайных значений, если не указано. Просто доказательство концепции на самом деле.Экземпляры класса Python являются дублирующими атрибутами

Однако по возрасту, полу и признакам расы по какой-то причине дублируются, хотя они генерируются функциями, которые должны возвращать случайные значения.

Я тестировал функции индивидуально, и они делают то, что они предполагают, и не являются сложными.

class NPC: 
    def __init__(self, gender = rand_gender(), race = rand_race(), 
       age = rand(16, 70),name = "", height = 0): 
     self.gender = gender 
     self.race = race 
     self.age = age 
     if name == "": 
      self.name = name_gen(self.gender) 
     else: self.name = name 
     if height == 0: 
      self.height = height_gen(self.race) 
     else: self.height = height 

def rand(min, max): 
    return random.randrange(min, max) 

def rand_gender(): 
    genders = ["Male", "Female"] 
    random.shuffle(genders) 
    return genders[0] 

def rand_race(): 
    races = ["Human", "Dwarf", "Elf", "Orc"] 
    random.shuffle(races) 
    return races[0] 

npc1 = NPC() 
npc2 = NPC() 
npc3 = NPC() 
hero = NPC("Female","Human", 26, "Hero") 

print npc1 
print npc2 
print npc3 
print hero 
print npc1 == npc2 

Это мое определение класса и его функции, с которыми у меня возникают проблемы. Функции имени и высоты и метод __str__ кажутся в порядке, поэтому я их не включил. Как вы видите, пол, возраст и раса дублируются. Почему это происходит? Можете ли вы использовать функции для инициализации объектов класса?

Выход:

Name: Jane Gender: Female Age:32 Race: Elf Height: 6.4 
Name: Wilma Gender: Female Age:32 Race: Elf Height: 6.7 
Name: Jane Gender: Female Age:32 Race: Elf Height: 6.5 
Name: Hero Gender: Female Age:26 Race: Human Height: 5.7 
False 
+1

По умолчанию значения аргументов устанавливаются, когда функция определена, поэтому, используя то же значение на всех вызовы к функции, которые следуют. – martineau

ответ

5

Это очень распространенная Гоча питона. Определение функции (в данном случае с именованными параметрами) выполняется только один раз! Таким образом, все значения по умолчанию устанавливаются только один раз.

class NPC: 
    def __init__(self, gender = rand_gender(), race = rand_race(), 
       age = rand(16, 70),name = "", height = 0): # run only once 

Попробуйте сделать что-то вроде

class NPC: 
    def __init__(self, gender = None, ...): 
     if gender is None: 
      gender = rand_gender() 
     # init the rest 

Как было предложено, здесь even more gotchas

+2

http://docs.python-guide.org/en/latest/writing/gotchas/ является хорошим объяснением проблемы, возможно, стоит упомянуть в дополнение к вашим объяснениям. –

+0

Ах, да! Я думал, что значения аргументов по умолчанию были созданы каждый раз, когда объект был создан из класса, я понимаю сейчас. Спасибо за элегантное объяснение. – DMcDonald

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