Python – Unable to access instances of classes

Unable to access instances of classes… here is a solution to the problem.

Unable to access instances of classes

I’m having a problem that might be very simple, but I can’t figure it out. I’m trying to develop a desktop app for creating schedules. I’m using Tkinter and Python 3.6. I have a Teacher class so users can create new instances with various properties.

class Teacher:
    """The properties of the teachers"""
    allTeachers = []
    def __init__(self, name, lessons, timeframe):
        self.name = name
        Teacher.allTeachers.append(self.name)
        self.lessons = lessons # number of lessons
        self.timeframe = timeframe

After creating a new instance, I check if it exists :

for obj in gc.get_objects():
    if isinstance(obj, Teacher):
        print(obj.name)

However, when the user adds another teacher, the above code indicates that there is still only one instance of the Teacher class (the newest one). Also, when I run the same code from another module (in the same directory), Python tells me that there is no instance of the Teacher class. Nevertheless, the class variable (allTeachers) keeps track of all teachers that have been added.

Am I missing some basics about who I’m accessing?

Solution

If you don’t hold any references to your instance, Python frees memory. You only store the teacher’s name – not an instance of it. So if you happen to create them like this:

Teacher("Hugo", None, "8am to 2pm")
Teacher("Claas", "some", "9am to 10am")

There are no references to the actual instances, and they are garbage collected.

Additional information can be read here: Python garbage collector documentation


If you want to look for something, if you have more than 4 items, the list is bad and they get the O(n) lookup. Use set or dict instead of O(1). If you want to find Teacher by name, dict comes in handy:

class Teacher:
    """The properties of the teachers"""
    allTeachers = {} # dict as lookup  is faster then list for 4+ teachers
    def __init__(self, name, lessons, timeframe):
        self.name = name
        Teacher.allTeachers[self.name] = self  # store the instance under its name
        self.lessons = lessons # number of lessons
        self.timeframe = timeframe

@classmethod
    def hasTeacher(cls,name):
        return name in Teacher.allTeachers

Teacher("Hugo", None, "8am to 2pm")
Teacher("Claas", "some", "9am to 10am")

import gc

print(Teacher.hasTeacher("Judith"))
print(Teacher.hasTeacher("Claas"))

for obj in gc.get_objects():
    if isinstance(obj, Teacher):
        print(obj.name)

Output:

False  # no teacher called Judith
True   # a teacher called Claas

# all the Teacher instances
Hugo
Claas

If you store Teacher instances

this way, you should probably provide a way to remove them from class variable instances by name – and possibly return Teacher – instances by name from them

Related Problems and Solutions