无法访问属性中的嵌套数据

问题描述 投票:0回答:1

我有两个班级(学生和课程)。我正在尝试为Course类编写一种方法,该方法将从课程中删除给定的学生。但是我跑步的时候有问题方法中的self.students.remove(student)。错误告诉我该学生不在学生列表中。打印学生列表时,我实际上看不到这些值,但是我看到了对它的引用:

print(self.students)
> [<data.Student object at 0x7fc9980334f0>, <data.Student object at 0x7fc998033580>, <data.Student object at 0x7fc9980428b0>, <data.Student object at 0x7fc998042a00>]

但是,如果我选择一个特定的学生作为索引,那么我就能看到实际的数据。

print(self.students[0])
> 2020411:King,Maha

为什么在尝试打印students属性时会发生这种情况?

如果需要的代码:

from copy import deepcopy


class Student:

    def __init__(self, sid, last, first):
        self.sid = sid
        self.last = last
        self.first = first

    def __str__(self):
        return '{}:{},{}'.format(self.sid, self.last, self.first)

    def __repr__(self):
        return '{}:{},{}'.format(self.sid, self.last, self.first)

class Course:

    def __init__(self, crn, students):
        self.crn = crn
        self.students = deepcopy(students)

    def key(self):
        return self.crn

    def is_empty(self):
        return len(self.students) == 0

    def get_student(self, student_key):
        for student in self.students:
            if student.key() == student_key:
                return deepcopy(student)
        return None

    def __contains__(self, student):   
        for i in self.students:
            if student.key() == i.key():
                return True
                break
        return False

    def register(self, student):
        if student not in self:
            self.students.append(deepcopy(student))
        return

    def drop(self, student):              
        s = None
        if student in self:
            s = deepcopy(student)
            self.students.remove(student)
        return s

student1 = Student(2020411, 'King', 'Maha')
student2 = Student(2019399, 'Hess', 'Alvin')
student3 = Student(2020301, 'Chin', 'Yu')
student4 = Student(2019111, 'Hay', 'Ria')
student_list = [student1, student2, student3]
course1 = Course('CP104', student_list)
removed_student = course1.drop(student2)
python
1个回答
0
投票

deepcopy()的问题在于,它创建了一个全新的对象,该对象具有与原始对象相同的属性,但是它们并不相等。对于list.remove(),这将比较参考以检查实际对象是否存在。您要尝试删除列表中未包含的对象。

代替删除它,如果您想返回学生,请使用list.pop()

def drop(self, student):
    for i, s in enumerate(self.students):
        if s.sid == student.sid :          
            return self.students.pop(i)

附带说明,如果Course.students是这样的字典,操作会更容易:

self.students = {
    `sid1`: student1,
    `sid2`: student2,
    # etc
}

编辑:或者,在__eq__()中实现Student,以便list.remove()可以工作。

def __eq__(self, other):
    return self.sid == other.sid and self.first == other.first and self.last == other.last
© www.soinside.com 2019 - 2024. All rights reserved.