Использование метода __lt__() принадлежит родительскому классу, даже если он переопределен

#python #python-3.x

#python #python-3.x

Вопрос:

 class Person:
    def __init__(self,name,grade):
        self.__name=name
        self.__grade=grade
    def __lt__(self,other):
        return self.__name<other.__name
    def __repr__(self):
        return '{} {}'.format(self.__name,self.__grade)
 
class Student(Person):
    def __init__(self,name,grade):
        Person.__init__(self, name, grade)
    def __lt__(self,other):
        return self._Person__grade<other._Person__grade
    
L=[]
student1=Student('Xavi',90)
student2=Student('Richard',100)
L.append(student1)
L.append(student2)
L.sort()
print(L)
 

 Expected Output:
[Richard 100,Xavi 90]
 

Здравствуйте, даже если я переопределю __lt__ метод в подклассе, я все равно хочу использовать __lt__() метод в суперклассе, как я могу это сделать? Я думаю, что вместо L.sort() прямого использования нам нужно вызвать __lt__ метод класса Person , но я не знаю, как это сделать.

Комментарии:

1. Что вы подразумеваете под «я все еще хочу использовать метод lt() в суперклассе»? Вы имеете в виду, что хотите получить результат из метода суперкласса, а затем добавить еще одно условие? А еще лучше, определите словами , что означает, что один ученик «меньше» другого?

2. Если вы хотите использовать оба, зачем переопределять его?

3. Поскольку я переопределяю метод lt в подклассе, он производит сравнение в соответствии с оценками, но я хочу, чтобы он производил сравнение в соответствии с именами.

4. Вы не переопределяли атрибут, поэтому вы можете использовать self.__grade вместо self._Person__grade .

5. Вместо того, чтобы пытаться получить доступ к методу родительского класса, используйте key аргумент to sort : L.sort(key=lambda x: x.grade) or L.sort(key=lambda x: x.name) . (Избавьтесь от имен __ с префиксом -; от них больше хлопот, чем пользы).

Ответ №1:

У объекта может быть только один __lt__ метод. Невозможно указать, что sort() следует использовать метод, отличный от других сравнений.

Вместо этого вы можете указать ключ в sort() вызове, чтобы он сортировался по именам вместо использования __lt__ метода самого объекта.

 L.sort(key = lambda(s): s._Person__name)
 

или

 import operator
L.sort(key = operator.attrgetter("_Person__name"))
 

Комментарии:

1. Большое спасибо, но есть ли какой-нибудь способ без использования лямбда-выражений? Я имею в виду, например, мы можем сказать что-то вроде Person . __lt__() вне классов. Мне действительно нужно такое выражение.

2. sort() не позволяет указать функцию сравнения, только ключевую функцию.

3. Хорошо, поэтому мы должны использовать лямбда-выражения для его решения.

4. Вы также можете использовать operator.attrgetter("_Person__name")

5. @blit Вы также можете определить метод, который возвращает имя, и использовать его.