Правильный способ записи функции repr с наследованием

я экспериментирую с ООП python, и я не был уверен в __repr__ наследование функции. Поскольку функция родительского класса выглядела так:

def __repr__(self):
    '''Returns representation of the object'''
    return("{}('{}')".format("Class name", self._param))

Я хотел знать, лучше ли использовать общий подход (который может быть подходящим и для детских классов), как следующий:

def __repr__(self):
    '''Returns representation of the object'''
    return("{}('{}')".format(self.__class__.__name__, self._param))

или, если это хорошая практика, чтобы переопределить функцию в каждом классе.

кроме того, Пожалуйста, игнорируйте часть кодировки, так как я ее оставляю позади.

3 ответов


и __repr__ имеет особое значение в модели данных Pythons:

object.__repr__(self)

называют repr() встроенная функция для вычисления" официального " строкового представления объекта. если это вообще возможно, это должно выглядеть как допустимое выражение Python, которое можно использовать для воссоздания объекта с тем же значением (учитывая соответствующую среду). Если это невозможно, строка формы <...some useful description...> должен быть возвращен. Возвращаемое значение должно быть строковым объектом. Если класс определяет __repr__() а не __str__(), потом __repr__() также используется, когда требуется "неофициальное" строковое представление экземпляра класса.

это обычно используется для отладки, поэтому важно, чтобы представление было богатым информацией и однозначным.

это означает строку, возвращаемую __repr__ должно использоваться для создания другого такого же объекта. Так __repr__ - это то, что очень часто требуется переопределение, а не из-за __class__.__name__ но потому, что "государство" должно быть захвачено в представлении.

def class A(object):
    def __init__(self, param):
        self._param = param

    def __repr__(self):
        '''Returns representation of the object'''
        return("{}('{}')".format(self.__class__.__name__, self._param))

тогда вы абсолютно должны переопределить __repr__ при добавлении параметров для __init__:

def class B(A):
    def __init__(self, param1, param2):
        self._param = param1
        self._param2 = param2

    def __repr__(self):
        '''Returns representation of the object'''
        return("{}('{}')".format(self.__class__.__name__, self._param, self._param2))

но в случае __repr__ суперкласса точно "описание" подкласс тогда нет смысла перегружать __repr__:

class B(A):
     pass

однако это всегда хороший выбор, чтобы использовать self.__class__.__name__ над жестким кодированием имени класса, на всякий случай, если вы или кто-то другой подклассы его.


Да - - это не просто "ок", но это то, что более практично почти в каждом проекте и иерархии классов.

на самом деле, это почти идеальный "пример учебника" о том, когда использовать наследование классов, и просто позволить коду в суперклассах использоваться повторно.


здесь вы можете посмотреть, как я унаследовал __repr__ метод из класса Pesron в классе Student.

Main():

def main():
    person_obj = Person("Jay", "26")  #Instance of Person class
    print(person_obj)
    st_obj = Student("Jenny", "24", "12345") #Instance of Student class
    print(st_obj)

базовый класс: человек

class Person:
    name = ""  
    age = 0  

    def __init__(self, personName, personAge):  
        self.name = personName  
        self.age = personAge  

    def __repr__(self):
        return "Hello.. greeting!! {} {} ".format(self.name, self.age) 

производный класс: студент

class Student(Person):
    studentId = ""  

def __init__(self, studentName, studentAge, studentId):  
    Person.__init__(self, studentName, studentAge)  
    self.studentId = studentId  

def __repr__(self):
    return super().__repr__() + " id is:  {} ".format(self.studentId)


if __name__ == '__main__':
    main()