繁体   English   中英

是否可以创建嵌套的 class 属性?

[英]Is it possible to create nested class attributes?

我对 Python 很陌生,最近了解了课程。 我一直在试验它们,并提出了一个学生/课程评分系统。 这是到目前为止的代码:

class course:
    TOTAL_COURSES = 0

    def __init__(self, name, room, max_students):
        self.name = name
        self.room = room
        self.max_students = max_students
        self.student_list = []
        course.TOTAL_COURSES += 1
 
    def addStudent(self, student):
        # Checks if the class is below max capacity
        if len(self.student_list) < self.max_students:
            self.student_list.append(student)
            # Adds the course to the student's course list
            student.course_list.append(self)
            return True
        return False

所以这创建了一个课程 class,我可以添加学生并设置他们的房间和其他东西。 我还有另一个 class,用于存储学生信息:

class student:
    TOTAL_STUDENTS = 0

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        # Courses in course_list are stored as objects
        self.course_list = []
        student.TOTAL_STUDENTS += 1

很简单; 我刚刚被困在如何创建实际的评分系统上。 如果我这样做:

s1 = student("Tom", 17, "Male")
c1 = course("English", "E123", 25)

然后可以使用“嵌套属性”吗? 所以我会将该学生的课程成绩分配给如下值:

s1.c1.grade = "A+"

但是,这不起作用,并引发(预期的)AttributeError。 那么我必须使用我之前创建的 course_list 吗?

s1.course_list[0].grade = "A+"

即使那样,我也不确定如何为该课程 object 评分。

成绩被分配给studentcourse object 的组合,因此它不能是其中任何一个的单个属性。

我会认为成绩与学生的关系比课程更密切,所以我会向student添加一个字典,其中一个唯一的课程 ID(例如它的名称)作为键,成绩作为值。 接下来,您可能需要 function 到 select 课程列表中具有给定 ID(名称)的课程。

为了进一步改进您的代码,您可以将course设置为可散列的 class,这是一个带有__hash__方法的 class(在 Python 文档中查找)。 然后,您可以直接将course对象用作字典键,而不是使用 ID。

这是一个解决方案,通过为学生分配“课程槽”而不是课程本身来解决上述一些问题。 正如您可能想象的那样,可用课程名额的数量是有限的,这取决于课程的最大规模。 代码可以进一步开发,但我认为这可能有助于您入门:

class Student:

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        self.courses = {}
        
    def addCourse(self, course):
        if course.status=='Enrolled':
            self.courses[course.name] = course
        else:
            self.courses[course.name] = course.status

            
class Course:

    def __init__(self, name, room, max_students):
        self.name = name
        self.room = room
        self.max_students = max_students
        self.student_list = []
        
        self.course_slots_filled = 0
        self.course_slots_available = max_students
        
    def __str__(self):
        return 'Course_object_{}'.format(self.name)
 
    def check_slots_available(self):
        if self.course_slots_filled < self.max_students:
            return True
        else:
            return False
    
    class CourseSlot:
        def __init__(self, name, student_name, status):
            self.name = name
            self.student_name = student_name
            self.status = status
            self.grade = 'No grade assigned'
        
        def __repr__(self):
            return 'CourseSlot_object_{}'.format(self.name)
        
        def set_grade(self, grade):
            self.grade = grade
            
    
    def assign_course_slot(self, student_name):
        if self.check_slots_available():
            self.course_slots_filled+=1
            self.course_slots_available-=1
            status = 'Enrolled'
            self.student_list.append(student_name)
        else:
            print('Sorry, {} class is full! {} not enrolled.'.format(self.name, student_name))
            status = 'Not enrolled'
            
        return self.CourseSlot(self.name, student_name, status)

示例用法

实例化课程:

physics = Course('Physics','101',5)
chemistry = Course('Chemistry','102',1)

实例化学生 1 并分配课程槽:

s1 = Student("Tom", 17, "Male")
s1.addCourse(physics.assign_course_slot(s1.name))
s1.addCourse(chemistry.assign_course_slot(s1.name))
s1.courses['Physics'].set_grade('A+')

[v for v in s1.courses.values()]

# >>> [CourseSlot_object_Physics, CourseSlot_object_Chemistry]

实例化学生 2 并分配课程槽

s2 = Student("Susan", 18, "Female")
s2.addCourse(physics.assign_course_slot(s2.name))
s2.addCourse(chemistry.assign_course_slot(s2.name))

#>>> Sorry, Chemistry class is full! Susan not enrolled.

获取课程信息:

print('Physics course slots filled: ',physics.course_slots_filled)
print('Physics course slots available: ',physics.course_slots_available)
print('Chemistry course slots filled: ',chemistry.course_slots_filled)
print('Chemistry course slots available: ',chemistry.course_slots_available)

#>>> Physics course slots filled:  2
#    Physics course slots available:  3
#    Chemistry course slots filled:  1
#    Chemistry course slots available:  0

print('Physics student list: ',physics.student_list)
print('Chemistry student list: ',chemistry.student_list)

# >>> Physics student list:  ['Tom', 'Susan']
#     Chemistry student list:  ['Tom']

for s in [s1,s2]:
    for c in s.courses.values():
        try:
            print('{} {} grade: {}'.format(s.name, c.name, c.grade))
        except AttributeError:
            pass

# >>> Tom Physics grade: A+
#     Tom Chemistry grade: No grade assigned
#     Susan Physics grade: No grade assigned

我猜作弊是课程student_list只获取学生的姓名,而不是 Student object,如果你传递一个唯一的 ID 然后遍历一个学生对象列表以匹配 ID,这可能会起作用。 无论如何都要考虑一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM