A.T.
A.T.

Reputation: 31

Python - cannot access instances of a class

I am stuck with a problem that is probably quite simple, yet I cannot figure it out. I am trying to develop a desktop application for creating timetables. I am using Tkinter and Python 3.6. I have a Teacher class, so the user can create new instances with various attributes.

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

Once a new instance is created I check that 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 says that the Teacher class still has only one instance (the latest one). Moreover, when I run the same code from another module (in the same directory), Python tells me that the Teacher class has no instances. In spite of this the class variable (allTeachers) keeps track of all the teachers that have been added.

Am I missing something basic about accessing objects?

Upvotes: 3

Views: 346

Answers (1)

Patrick Artner
Patrick Artner

Reputation: 51673

Python frees memory, if you do not hold any reference to your instances. You are only storing the Teacher's names - not the instances of it. So if you happen to just create them like this:

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

there is no reference to the actual instance and they get garbage collected.

Additionally information can be read here: Python garbage collector documentation


If you want to look up things, lists are bad if you have more then around 4 items, they got a Lookup of O(n). Use a set or dict for O(1) instead. If you want to lookup Teacher by name, dict would be convenient:

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 probably should provide a way to remove them by name from the class variable instance as well - and maybe return the Teacher-instance by name from it

Upvotes: 3

Related Questions