#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)