1

I'm trying to play with Python's classes. I've created a Person() that just defines someone, with a "brother" attribute. Now, what I'm trying to do is to instanciate a Person and add all the others Person objects to his "brother" attribute. Now my problem is that even if I've added a check to make sure that I don't add the object himself to the brothers attibutes, it happens. Here's my code:

class Person():
    def __init__(self, name, bros=[]):
        self.name = name
        self.bros = bros

    def has_bros(self):
        if len(self.bros) >0 :
            return True
        return False

    def get_name(self):
        return self.name

    def add_bro(self, bro):
        if not bro.get_name() in [b.get_name() for b in self.bros] and bro.get_name() != self.name:
            self.bros.append(bro)
        print(f"param {self.name} has bros: {[brow.get_name() for brow in self.bros]}")

    def get_bros(self):
        return self.bros

people = ["Martin", "Charles", "Miriam", "Etienne"]

final_list = list()

for person in people:
    current_guy = Person(person)
    for existing_person in final_list:
        existing_person.add_bro(current_guy)
        current_guy.add_bro(existing_person)
    final_list.append(current_guy)

print("List of Persons with bros:")
for p in final_list:
    print(f"Person name: {p.get_name()}, his bros :{[bro.get_name() for bro in p.get_bros()]}")

I'm doing something wrong but I can't find what ^^' Can someone explain to me why this isn't working ?

Thanks folks !

  • Mutable default arguments aren't a good idea in Python, all your persons share the same list of brothers. – L3viathan Dec 05 '20 at 14:15

1 Answers1

0

Replace your __init__ method with:

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

Otherwise, the same list gets used whenever you initialize Person without explicitly giving a list of bros. A simpler example to demonstrate what's going on:

def test(default=[]):
    default.append(1)
    print(default)

Calling this three times:

>>> test()
[1]
>>> test()
[1, 1]
>>> test()
[1, 1, 1]
L3viathan
  • 26,748
  • 2
  • 58
  • 81