Reputation: 31
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
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