2

I want to store sorted instances of Student class, into Students class. And I am using staticmethod in Students class for sorting. I could be wrong, but the design seems a bit ugly and want to avoid using static method (the most ideal way in my mind is using a class method in class Student which returns student ID, and use this method for sorting, but it seems not an easier way to set a class method of class Student in class Students for sorting), if there is a better design, appreciate if you could share,

class Student:
        def __init__(self, id):
                self.id = id

class Students:
        def __init__(self, students):
                self.sortedStudents = sorted(students, key=Students.getStudentID)
        @staticmethod
        def getStudentID(student):
                return student.id

        def dumpAllStudents(self):
                for student in self.sortedStudents:
                        print student.id

students = []
students.append(Student(100))
students.append(Student(90))
students.append(Student(80))

allStudents = Students(students)
allStudents.dumpAllStudents()

thanks in advance, Lin

2
  • I don't understand you code design - why did you create a getter for the Student.id field inside the Students class? The getStudentID method is redundant Commented Apr 19, 2015 at 6:00
  • @mittelmania, good point, I can, but how to refer this method in Students class for sorting? Thanks. Commented Apr 19, 2015 at 6:02

3 Answers 3

2

Using operator.attrgetter:

import operator
...

def __init__(self, students):
    self.sortedStudents = sorted(students, key=operator.attrgetter('id'))

operator.attrgetter('id') returns a callable that returns the attribute id from the operand. So it can be used instead of the static method or lambda.

Sign up to request clarification or add additional context in comments.

Comments

2

You could use a lambda expression instead:

class Students:
    def __init__(self, students):
        self.sortedStudents = sorted(students, key=lambda s: s.id)
    ...

Whether you want to do this or have your Student class itself be comparable (see tzaman's answer) depends a bit on the rest of your code and your intent. If you need an order on students elsewhere, include the ordering in the Student class. If you only want them ordered inside your Students class, use my approach.

From an OOP design perspective, I wouldn't consider students to be ordered in general, but that's for you to decide (and may in the end be a matter of convenience).

Comments

1

If your objective is just to sort Student's instance based on its id, you don't need another function or method for that. You can achieve this using lambda expression.

class Student:
        def __init__(self, id):
                self.id = id

class Students:
        def __init__(self, students):
                self.sortedStudents = sorted(students, key=lambda stud: stud.id) 

        def dumpAllStudents(self):
                for student in self.sortedStudents:
                        print student.id

students = []
students.append(Student(100))
students.append(Student(90))
students.append(Student(80))

allStudents = Students(students)
allStudents.dumpAllStudents()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.