inner classes of python loop referencing the same memory and assigning the last referenced variable

Question:

So im learning python and am trying to build a python file with inner classes and im trying to populate subjects as an array inside a class. However, it seems to be pointing to the same memory even though i am using a dictionary to ensure it does not happen. Is there any way for me to fix this issue?

I am trying to assign 2 subjects to my student. However, when accessing the name of the subjects, it is returning me the same subject which is located at the 1st index.

I’m used to java where i can just create a new instance of a class using the new tag.

class Student:
    class Subject:
        def __init__(self):
            self.name = ''

    def __init__(self):
        self.name = ''
        self.subject = self.Subject()
        self.courses = {}


def test():
    courses = ['Subject A', 'Subject B']
    student = Student()
    student.name = 'apple'
    for i, course in enumerate(courses):
        student.courses[i] = student.subject
        student.courses[i].name = course

    print(student.courses[0].name)
    print(student.courses[1].name)


test()

Thank you very much for the help! I am struggling to get a grasp of this.

Asked By: Min UD

||

Answers:

The class is an object itself, so when you run

        student.courses[i] = student.Subject

you are not creating an instance of the class, you are setting the "static" class.

When you override the name here, you are doing it for the shared class.

student.courses[i].name = course

A fix would be:

        student.courses[i] = student.Subject()

Here is a more idiomatic python way of writing your program, just something to ponder. In particular, I rarely see inner classes referenced via self.XXX, but as you can see it works.

class Student:
    class Subject:
        def __init__(self, name=None):
            self.name = name

        def __str__(self):
            return 'subject is "%s"' % self.name

    def __init__(self, name=None):
        self.name = name
        self.courses = []

    def addcourse(self, name):
        self.courses.append(Student.Subject(name))


def test():
    subjects = []
    courses = ["Subject A", "Subject B"]
    student = Student(name="Student A")
    for course in courses:
        student.addcourse(course)
    print(student.courses[0])
    print(student.courses[1])

Answered By: toppk
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.