Как вывести все атрибуты класса в виде списка

Создал класс Car и добавил парочку функций. После добавления свойства машины, необходимо вывести все данные о машине(т.е. объект). При print(brichka) выводит <__main__.Car object at 0x000002127E7A6BA0>, т.е. место класса, название, тип объекта и адрес в памяти. Попытался реализовать вывод с помощью списка, а точнее с помощью неявного итератора цикла for и добавления к списку info. Однако возникают вопросы: как я могу итерировать object и почему компилятор не бьет по info.append(), если я не объявлял список?. А также, почему self не может являться объектом итерации (возможно ответ кроется в первом вопросе)? По итогу не могу сложить 2+2 и вывести атрибуты объекта в любом читабельном виде.

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def _Property(self, isProperty):
        self.isProperty = isProperty

    def Get_Car(self):
        for prop in self:
            if not prop.startswith('_'):
                info.append(prop)
        return info


brichka = Car("Toyota", "Mark")
brichka._Property(str(input()))
print(brichka.Get_Car())

UPD: Вообще, понимаю, что можно обойтись closure и decorator. У меня получилось, что-то вроде этого:

def Car(func):
    def Has_the_property(*_property):
        print(func(*_property))
    return Has_the_property

def Some_property(*_property):
    return f"{_property}"

addProperty = Car(Some_property)
addProperty(str(input()))

Однако, при попытке реализовать через класс, возникла трудность с выводом информации об объекте.


Ответы (2 шт):

Автор решения: CrazyElf

Если вам нужно просто напечатать всю информацию об объекте в читабельном виде, причём все названия свойств объекта вы заранее знаете, то просто реализуйте метод класса __str__:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def __str__(self):
        return f"Бренд: {self.brand}, модель: {self.model}"

brichka = Car("Toyota", "Mark")
print(brichka)

Вывод:

Бренд: Toyota, модель: Mark

А если вам реально нужны какие-то произвольные свойства объекта, то добавляйте их просто в какой-то список или словарь в объекте. Очень редко может понадобиться добавлять к классу произвольные свойства именно как поля объекта. Да это и не безопасно для класса.

Update
Пример с произвольными свойствами:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model
        self.props = {}

    def __str__(self):
        props = ', '.join(f'{key}: {val}' for key, val in self.props.items())
        return f"Бренд: {self.brand}, модель: {self.model}, {props}"

    def append(self, key, val):
        self.props[key] = val

brichka = Car("Toyota", "Mark")
brichka.append("цвет", "чёрный")
brichka.append("тонировка", "имеется")
print(brichka)

Вывод:

Бренд: Toyota, модель: Mark, цвет: чёрный, тонировка: имеется
→ Ссылка
Автор решения: Vladimir Bogdanov

Возможно рискну прослыть "капитаном очевидность", но Вы уже были очень близко к ответу на свой вопрос. Да и @andreymal уже подсказал это решение в комментариях. Одно НО: представленный ниже код выведет список атрибутов экземпляра, а не самого класса. В вашем коде у класса вообще нет атрибутов, кроме встроенных вида __atr__ и двух методов _Property и Get_Car. Но, насколько я понял, Вам как раз нужны атрибуты экземпляра. Еще одно маленькое НО: все это будет работать, пока Вы не используете __slots__. Любые новые атрибуты будут автоматически выводится в списке. Python за вас создает словарь с атрибутами и значениями, потому доп. списки и словари лишь трата памяти.

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def _Property(self, isProperty):
        self.isProperty = isProperty

    def Get_Car(self):
        return self.__dict__.keys()
→ Ссылка