我对Python非常陌生,我正在努力解决类与继承等之间的关系。
假设我有一个类Student
class Student():
def __init__(self, name):
self.name = name
def get_name(self):
return self.name
def set_name(self, name):
self.name = name这位学生可以参加多门课程:
class Course():
def __init__(self, title):
self.title = title
def get_title(self):
return self.title
def set_title(self, title):
self.title = title每门课程也可以有多个学生。所以这是一种manyToMany关系。我的第一个想法是创建第三个类,名为StudentCourse
class StudentCourse(Student, Course):
student_courses = {}
def __init__(self, student, course):
self.student = student
self.course = course
def add_student_to_course(self, student, course, results):
self.student_courses[student] = {
'course': course,
'results': results
}
def get_student_courses(self, student):
return self.student_courses.get(student)这个结构正确吗?如果是这样,我的问题是:在学生类中,如何访问包含特定学生的课程和结果的student_courses字典?
编辑--我希望能够看到哪些学生参加了特定的课程,并获得了每个参加课程的学生的结果。
期待你的回复。
发布于 2018-09-20 19:00:17
这更像是一个基于观点的问题,而不是你能得到一个明确答案的问题。尽管如此,考虑到Student和Course都是两个非常不同的实体,只有所有权才能连接到一起,因此没有必要在两者之间创建一个被屏蔽的类。
相反,我建议让他们两人以双链接的方式处理多到多关系中的一部分,即当你将Student添加到Course中时,你也会通知Student,他们现在是这门课程的一部分,反之亦然。类似于:
class Student(object):
def __init__(self, name):
self.name = name
self.courses = {} # we'll use a dict so that our courses can be mapped to results
def add_course(self, course):
if course not in self.courses:
self.courses[course] = {} # initialize each course with an empty dict
# feel free to use any fields you like, like results etc.
course.add_student(self)
def del_course(self, course):
self.courses.pop(course, None)
course.del_student(self)
def __repr__(self): # just to ease our printouts
return self.name和:
class Course(object):
def __init__(self, title):
self.title = title
self.students = set() # a set ought to be enough
def add_student(self, student):
self.students.add(student)
student.add_course(self)
def del_student(self, student):
self.students.discard(student)
student.del_course(self)
def __repr__(self): # just to ease our printouts
return self.title然后你可以在两个方向上使用它们来建立你的多到多的关系,例如:
# Create some students and courses
john = Student("John Doe")
jane = Student("Jane Doe")
foo = Course("Foo Course")
bar = Course("Bar Course")然后:
# initial state
print("John courses: {}".format(john.courses)) # John courses: {}
print("Jane courses: {}".format(jane.courses)) # Jane courses: {}
print("Foo students: {}".format(foo.students)) # Foo students: set([])
print("Bar students: {}".format(bar.students)) # Bar students: set([])
# lets add John to Foo:
john.add_course(foo)
print("John courses: {}".format(john.courses)) # John courses: {Foo Course: {}}
print("Foo students: {}".format(foo.students)) # Foo students: set([John Doe])
# lets add Jane to Bar, the other way around
bar.add_student(jane)
print("Jane courses: {}".format(jane.courses)) # Jane courses: {Bar Course: {}}
print("Bar students: {}".format(bar.students)) # Bar students: set([Jane Doe])
# lets add John to Bar as well
bar.add_student(john)
print("John courses: {}".format(john.courses))
# John courses: {Foo Course: {}, Bar Course: {}}
print("Bar students: {}".format(bar.students))
# Bar students: set([Jane Doe, John Doe])
# finally, lets add some info for the Foo course to John
john.courses[foo]["results"] = 94
print("John courses: {}".format(john.courses))
# John courses: {Foo Course: {'results': 94}, Bar Course: {}}考虑到我们使用本机结构--集合和字典--来保存我们的关系,我们不仅可以自动防止重复条目,我们还可以很容易(非常快)检查关系,例如:
print("John is in Bar: {}".format(john in bar.students)) # John is in Bar: True
# or:
print("Bar is in John's courses: {}".format(bar in john.courses))
# Bar is in John's courses: True
print("Jane is in Foo: {}".format(jane in foo.students)) # Jane is in Foo: False然后,您可以对其进行扩展,例如,将正在存储的结果和类似的结构正式化--您可以继续开发API以满足您的需要。祝好运!
发布于 2018-09-20 18:36:44
继承几乎肯定是表达Students和Courses之间关系的错误方式。继承表示IS-A关系。你的学生既不是课程,也不是你的课程学生。我也是-A错了。
你可能想要的是.每个Student都有--他们注册了许多Course。类似地,每个Course都注册了几个Student。在数据库中,您可以创建relationship对象来处理多到多的关系,但是在Python代码中,您可以使用数据结构。一份清单是自然的选择。下面的设计为每个学生添加了一个课程列表,并为每个课程添加了一个学生列表:
class Student:
def __init__(self, name):
self.name = name
self.courses = []
def enroll(self, course):
self.courses.append(course)
course.students.append(self)
class Course():
def __init__(self, title):
self.title = title
self.students = []
def enroll_student(self, student):
student.enroll(self)关于getter和setter的说明(与您的主要问题无关):您通常不需要用Python编写像get_name和set_name这样的方法。通常,如果这些方法没有执行任何操作(比如验证输入或以某种方式转换输出),则应该直接使用该属性。在其他语言中,编写和使用此类方法通常是最佳实践,即使您还不需要这些方法,但是在Python中,如果您后来决定需要进行一些验证,则可以使用property将属性查找的实现更改为方法调用。
https://stackoverflow.com/questions/52430876
复制相似问题