Доступ к переменным класса с помощью __repr__()

Я относительно новичок в Python, и мне было интересно, как можно "настроить" класс так, чтобы он возвращал кортеж, если вы его печатаете.

Пример: у меня есть класс с атрибутами a, b & c:

class Foo:
    def __init__(self):
        self.a = 3
        self.b = 4
        self.c = 5

Теперь, как мне "настроить" класс так, чтобы я мог получить доступ к этим атрибутам следующим образом:

>>> bar = Foo()
>>> print bar
<foo(3, 4, 5)>
>>> print bar[1]
4

я знаю __repr__() а также __str__(), но если я пытаюсь получить доступ к номерам через "[]", возникает следующая ошибка:

AttributeError: Foo instance has no attribute '__getitem__'

Я знаю, что это возможно как-то, как пример pygame библиотека имеет объект под названием Rect который работает именно так, как описано выше.

Спасибо!

3 ответа

Решение

Как AttributeError говорит, что вам нужно определить __getitem__ метод для вашего класса:

class Foo:
    def __init__(self):
        self.a = 3
        self.b = 4
        self.c = 5

    def __getitem__(self, index):
        if index == 0:
            return self.a
        elif index == 1:
            return self.b
        elif index == 2:
            return self.c
        else:
            raise KeyError("Index must be 0, 1 or 2")

Некрасиво, но работает

>>>bar = Foo()
>>>print bar
<__main__.Foo instance at xxxxxxxxxxxx>
>>>print bar[1]
4

Если вам не нужно a, b а также c чтобы быть отдельными переменными, вы можете использовать:

class Foo:
    def __init__(self):
        self.elements = [3, 4, 5]

    def __getitem__(self, index):
        return self.elements[index]

Хотя в этом случае я хотел бы рассмотреть возможность использования list непосредственно...

У вас есть два совершенно разных вопроса здесь. Если вы установите значение как self.a, вам нужно получить к нему доступ как self.a, не используется [], Просто возьми свой __str__ сделать что-то вроде:

return '<foo({0}, {1}, {2})>'.format(self.a, self.b, self.c)

Если вы хотите иметь доступ к этим переменным, используя []тогда вам нужно определить __getitem__ как описано в ответе Стефано Санфилиппо и в документации.

Не уверен, что это именно то, что вы хотите. Установка значений как self.a будет доступна с print bar.a, Однако, небольшой обходной путь, когда вы устанавливаете все собственные значения, формируется словарь. Вы можете получить массив, извлекая значения из всех атрибутов self.

>>> bar = Foo()
>>> print bar
<foo(3, 4, 5)>
>>> bar.__dict__
{'a': 3, 'b': 4, 'c': 5}
>>> bar.__dict__.values()
[3,4,5]
Другие вопросы по тегам