Not understanding python nested class instances

I’m having a misunderstanding about python classes/variables when used in an array. Given the below example, I would expect each ‘basket’ to have only one ‘apple’. Yet each one ends up with 5? Why is that and how can I fix my code?

class Apple:
    def __init__(self):
        return

class Basket:
    apples: list[Apple] = list()
    def add_apple(self, apple):
        self.apples.append(apple)

baskets = list()
for i in range(5):
    # I'm instantiating a new basket here, why do apples keep getting added to the 'old' baskets that are in the baskets array?
    b = Basket()
    a = Apple()
    b.add_apple(a)
    baskets.append(b)

for b in baskets:
    print(len(b.apples))

>Solution :

You’ve defined Basket.apples as a class attribute, meaning it’s shared by all Basket instances! Make it an instance attribute by defining it in __init__ and attaching it to the self instance:

class Apple:
    pass


class Basket:
    def __init__(self) -> None:
        self.apples: list[Apple] = []

    def add_apple(self, apple: Apple) -> None:
        self.apples.append(apple)

Each time you make a new Basket, Basket.__init__ is called on the new instance, and self.apples = [] is executed, creating a new list that belongs to the new instance. Now if you execute the rest of the code, you get the output:

1
1
1
1
1

because each basket contains one unique Apple.

Leave a Reply