Задать вопрос
@lok101

Как получать значение атрибута, обращаясь к экзмепляру класса?

Есть класс такого типа:

class Menu:
    storage: list = [1, 2, 3]


Когда я создам экземпляр этого класса и обращусь к нему без указания атрибутов или методов, я получу ссылку на экземпляр. Пример:

menu = Menu()
print(menu)

>>> <__main__.Menu object at 0x00000183ADFF5BA0>


Могу ли я сделать так, что бы при обращении к экземпляру класса без указания атрибутов я получал ссылку не на сам экземпляр, а на указанный в классе атрибут? Как это можно реализовать? В данном случае я хочу получать ссылку на атрибут storage. Пример:

menu = Menu()
menu.append(4)
print(menu)

>>> [1, 2, 3, 4]


В обычном случае код работать не будет и появится исключение, потому что для класса "Menu" не реализован метод "append".
  • Вопрос задан
  • 176 просмотров
Подписаться 1 Простой 3 комментария
Решения вопроса 3
fenrir1121
@fenrir1121
Начни с документации
Берете и реализуете
class Menu:
    storage: list = [1, 2, 3]

    def __str__(self):
        return f'[{", ".join(map(str, self.storage))}]'

    def append(self, value):
        self.storage.append(value)


In [2]: menu = Menu()

In [3]: menu.append(4)

In [4]: print(menu)
[1, 2, 3, 4]
Ответ написан
Комментировать
Vindicar
@Vindicar
RTFM!
Есть несколько способов.
1. Пусть твой класс наследуется от collections.abc.MutableSequence и сам реализует минимально нужный набор методов (__getitem__, __setitem__, __delitem__, __len__, insert). Остальные методы списка MutableSequence реализует за тебя. Разумеется, если твое поле - не список, то нужно будет наследоваться от другого класса.
2. Если твой класс всегда будет полем другого класса, ты можешь реализовать метод __get__(). Через него работают свойства (property). Но имей ввиду, что в этом случае ты вообще никогда не сможешь обратиться к чему-либо кроме того поля, которое возвращаешь.
Ответ написан
Комментировать
Первое стоит не забывать, что у вас storage - принадлежит классу а не отдельно экземплярам
Ну и в целом если почитать про магические методы, то можно узнать очень много полезного и интересного
from typing import List


class Menu:
    storage: List = []

    def __str__(self):
        return str(self.storage)

    def __getattr__(self, item):
        if item not in self.storage.__dir__():
            raise AttributeError(f'Нет такого метода {item}')

        return getattr(self.storage, item)

    def append(self, item):
        self.storage.append(item)


menu = Menu()

menu.append(10)

print(menu)

menu.extend((11, 12,))

print(menu)

menu.not_method(10)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@GoldGoblin
нужно переопределить __str__ у объекта.
Магический метод __str__ возвращает текстовое представление объекта
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы