__getattr__ для возврата индекса списка

#python #python-3.x

#python #python-3.x

Вопрос:

Я пытаюсь получить индекс (ID) элементов списка и иметь возможность вызывать его по их имени в качестве атрибута.

 class Page_ids(object):

    def __init__(self):
        self.values = ['PAGE1', 'PAGE2', 'PAGE3', 'PAGE4']

    def __getattr__(self, name):
        return self.values.index(name)

print(Page_ids.PAGE3)
  

В этом примере печать должна возвращать 2, но она возвращает :

 AttributeError: type object 'Page_ids' has no attribute 'PAGE3'
  

Чего мне не хватает?

Комментарии:

1. __getattr__ будет вызываться при обращении к атрибутам экземпляра Page_ids , а не к самому классу.

2. И можно ли это сделать при вызове самого класса? (Метакласс?)

3. Я понимаю, что вы могли бы определить __getattr__ в метаклассе, если это то, что вы хотите.

4. Конечно, даже если вы заставите его работать с использованием метаклассов, он __init__ не будет вызван и self.values не будет определен, поэтому вам нужно будет полностью изменить всю реализацию, если это то, что вы хотите.

5. Как насчет использования SimpleNamespace(**dict(zip([f'PAGE{x}' for x in range(1, 5)], range(4)))) из types стандартной библиотеки?

Ответ №1:

__getattr__ вызывается только в экземпляре класса, поэтому вам нужно его создать.

 class Page_ids(object):

    def __init__(self):
        self.values = ['PAGE1', 'PAGE2', 'PAGE3', 'PAGE4']

    def __getattr__(self, name):
        return self.values.index(name)

page = Page_ids()
print(page.PAGE3)
  

Комментарии:

1. Вы также могли бы вызвать print(Page_ids().PAGE3) .

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

Ответ №2:

Итак, мне наконец удалось, я полагался на структуру, используемую в Python2, не работающую в Python3.

Вот мой новый код для Python 3 :

 class Meta(type):
    def __getattr__(self, name):
        return self.values.index(name)
    def name_of(self, i):
        return self.values[i]

class Page_ids(object, metaclass=Meta):
    values = ['PAGE1', 'PAGE2', 'PAGE3', 'PAGE4']

print(Page_ids.PAGE3)