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