Python类的结构和继承

时间:2018-09-20 18:07:37

标签: python

我对Python很陌生,我正在尝试弄清类与继承等之间的关系。

假设我有一个((IJavaScriptExecutor)driver).ExecuteScript("document.body.style.zoom = '50%'"); 班:

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

这是正确的结构吗? 如果是这样,我的问题是:在Student类中,如何访问包含特定学生的课程和结果的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) 词典?

编辑 我希望能够查看哪些学生参加了特定课程,并获得每个参加该课程的学生的成绩。

期待您的回复。

2 个答案:

答案 0 :(得分:4)

几乎可以肯定,继承是表达StudentCourse之间关系的错误方法。继承表示IS-A关系。您的学生既不是课程,也不是课程的学生。因此IS-A是错误的。

您可能想要的是HAS-A。每个Student已注册了Course个。类似地,每个Course也注册了多个Student。在数据库中,您将创建关系对象来处理多对多关系,但是在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_nameset_name之类的方法。通常,如果这些方法没有执行任何操作(例如,验证输入或以某种方式转换输出),则应直接使用该属性。在其他语言中,通常最好的方法是始终编写和使用此类方法,即使您尚不需要它们,但在Python中,如果您以后决定确实需要进行一些验证,则可以更改属性的实现。使用property查找方法调用。

答案 1 :(得分:0)

这更多是基于观点的问题,而不是您可以明确回答的问题。话虽这么说,假设StudentCourse都是两个非常不同的实体,仅通过 ownership 连接,所以没有必要在这两个实体之间创建一个混合类

相反,我建议让他们两个都以双向链接的方式处理多对多关系,例如,当您向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。祝你好运!