Не выводит экземляры

Рейтинг: 0Ответов: 1Опубликовано: 29.03.2023

введите сюда описание изображения

Обучаюсь у Лутса, или у него опечатка или у меня лыжи не едут, но по итогу обращается не к тому методу - у меня код обращается к ListInherited, а не к Sub1

файл lister.py

class ListInstance:
    '''
    Приместный класс, реализующий получение форматированной строке при вызове функций print() и str() с экземляром в
    виде аргумента, через наследование метода __str__, реализованного здесь: отображает только атрибуты экземляра;
    self - экземляр самого нижнего класса в дереве наследования; во избежание конфликтов с именами атрибутов
    клиентских классов использует имена вида __X
    '''
    def __str__(self):
        return '<Instance of %s, address %s:\n%s>' % (self.__class__.__name__, id(self), self.__attrnames())
    def __attrnames(self):
        result = ''
        for attr in sorted(self.__dict__):
            result += '\tname %s=%s\n' % (attr, self.__dict__[attr])
        return result
class ListInherited:
    '''
    Использует функцию dir() для получения списка атрибутов самого экземляра и атрибутов, унаследованных экземляром от
    его классов: в Puthon 3.0 выводится больше имен атрибутов, чем в 2.6, потому что классы нового стиля в конечном
    итоге неследуют суперкласс object; метод getattr() позволяет получить значения унаследованных атрибутов,
    отсутсвующих в self.__dict__; реализует метод __str__, а не __repr__, потому что в противном случае данная
    реализация может попасть в бесконечный цикл при выводе связанных методов!
    '''
    def __str__(self):
        return '<Instance of %s, address %s:\n%s>' % (self.__class__.__name__, id(self), self.__attrnames())
    def __attrnames(self):
        result = ''
        for attr in dir(self):  # Передать экземляр функции dir()
            if attr[:2] == '__' and attr[-2:] == '__':  # пропустить внутренние имена
                result += '\tname %s=<>\n' % attr
            else:
                result += '\tname %s=%s\n' % (attr, getattr(self, attr))
            return result

файл main.py

from lister import *  # Импортировать инструментальные классы


class Super:
    def __init__(self):  # Метод __init__ суперкласса
        self.data1 = 'spam'  # Создать атрибуты экземляра

    def ham(self):
        pass


class Sub(Super, ListInstance):  # Подмешать методы ham и __str__
    def __init__(self):  # Инструментальные классы имеют доступ к self
        Super.__init__(self)
        self.data2 = 'eggs'  # Добавить атрибуты экземляра
        self.data3 = 42

    def spam(self):  # Определить еще один метод
        pass


class Sub1(Super, ListInherited):
    def __init__(self):
        Super.__init__(self)
        self.data4 = 'wtf'
        self.data5 = 85

    def spam(self):
        pass


if __name__ == '__main__':
    X = Sub()
    print(X)  # Вызовет подмешанный метод __str__
    Y = Sub1()
    print(Y)

Результат:

<Instance of Sub, address 1585766068112:
    name data1=spam
    name data2=eggs
    name data3=42
>
<Instance of Sub1, address 1585766070800:
    name _ListInherited__attrnames=<bound method ListInherited.__attrnames of <__main__.Sub1 object at 0x000001713705FA10>>
>
<Instance of C, address 1585766071696:
    name a=1
    name b=2
    name c=3

такой должен быть результат - картинка вверху страницы

Ответы

▲ 1

В методе __attrnames у ListInherited вызов return внутри цикла, а не после:

class ListInherited:
    ...
    def __attrnames(self):
        result = ''
        for attr in dir(self):  # Передать экземляр функции dir()
            if attr[:2] == '__' and attr[-2:] == '__':  # пропустить внутренние имена
                result += '\tname %s=<>\n' % attr
            else:
                result += '\tname %s=%s\n' % (attr, getattr(self, attr))
            return result
#      ^^^^^^^^^^^^^^^^^^