I have an infuriating problem with the code below. I have some objects which each hold internally a list of other objects. The code creates a new instance of a 'two' object, adds it into the 'three' object collection, and then creates a random number of 'one' objects and adds them into the newly created 2 object. When I iterate through three's collection of two objects, I expect to see that each two object has a random number of one objects, but in fact I see that all two objects have the same number of one objects.
What on earth am I doing wrong, or not understanding?
from typing import List
from random import randrange
class one:
    __name: str = None
    def __init__(self, name: str):
        self.__name = name
    def get_name(self):
        return self.__name
class two:
    __name:str = None
    __ones: List[one] = []
    def __init__(self, name: str):
        self.__name = name
    def get_name(self):
        return self.__name
    def num_ones(self) -> int:
        if not self.__ones:
            return 0
        return len(self.__ones)
    def __eq__(self,other):
        if not other:
            return False
        if not isinstance(other, self.__class__):
            return False
        if self.get_name() == other.get_name():
            return True
        return False
    def __str__(self):
        ret = self.get_name()
        ret += " ones:"
        ret += str(self.num_ones())
        return ret
    def add_one(self, name: str):
        for o in self.__ones:
            if o.get_name() == name:
                return o
        foo = one(name)
        self.__ones.append(foo)
class three:
    __twos: List[two] = []
    def __init__(self):
        pass
    def add_two(self, t:two):
        for i in self.__twos:
            if i == t:
                return o
        self.__twos.append(t)
    def __str__(self):
        ret = "twos:"
        ret += str(len(self.__twos))
        return ret
athree = three()
for i in range(1,60):
    #create a new two object
    atwo = two("two0" + str(i))
    #print the two object, it should contains zero one objects
    #because it's only just been created
    #but instead it contains the same as all other instances of two objects
    print(str(atwo))
    #add newly created object into a collection of two objects
    athree.add_two(atwo)
    #now create a random number of one objects and 
    #add them into our newly created two object
    #so we expect three to contains 60 two objects each
    #with a random number of one objects in them.
    rand = randrange(20)
    for o in range(1,rand):
        aone = atwo.add_one("one0" + str(o))
example output
..
two044 ones:17
two045 ones:17
two046 ones:17
..
here we expected to see that the number of 'ones' in each 'two' is random, but all sixty instances of two contains 17 ones!?
EDIT:
following the answer, which is that in Python properties declared in the body of the class are static until assigned by a method (usually the constructor), here is the working code :
from typing import List
from random import randrange
class one:
    __name: str = None
    def __init__(self, name: str):
        self.__name = name
    def get_name(self):
        return self.__name
class two:
    __name = None
    __ones: List[one] = None
    def __init__(self, name: str):
        self.__name = name
        self.__ones: List[one] = []
    def get_name(self):
        return self.__name
    def num_ones(self) -> int:
        if not self.__ones:
            return 0
        return len(self.__ones)
    def __eq__(self,other):
        if not other:
            return False
        if not isinstance(other, self.__class__):
            return False
        if self.get_name() == other.get_name():
            return True
        return False
    def __str__(self):
        ret = self.get_name()
        ret += " ones:"
        ret += str(self.num_ones())
        return ret
    def add_one(self, name: str):
        for o in self.__ones:
            if o.get_name() == name:
                return o
        foo = one(name)
        self.__ones.append(foo)
class three:
    __twos: List[two] = None
    def __init__(self):
        self.__twos: List[two] = []
    def add_two(self, t:two):
        for i in self.__twos:
            if i == t:
                return o
        self.__twos.append(t)
    def __str__(self):
        ret = "twos:"
        ret += str(len(self.__twos))
        return ret
athree = three()
for i in range(1,60):
    #create a new two object
    atwo = two("two0" + str(i))
    #add newly created object into a collection of two objects
    athree.add_two(atwo)
    #now create a random number of one objects and 
    #add them into our newly created two object
    #so we expect three to contains 60 two objects each
    #with a random number of one objects in them.
    rand = randrange(20)
    for o in range(1,rand):
        aone = atwo.add_one("one0" + str(o))
    print(str(atwo))
