#python
Вопрос:
Распространенная идиома, которую я использую, звучит примерно так: (кстати, итератор не работает):
SUMMARY = 'summary'
REPORT = 'report'
class PDF_TYPES:
summary = SUMMARY
report = REPORT
class __metaclass__(type):
def __iter__(self):
return iter(list(self.summary, self.report))
Во-первых, это много шаблонов для 2 значений.
Я хотел бы определить некоторые константы в списке и иметь возможность:
- Обращайтесь к ним индивидуально, например
REPORT
, как указано выше - Импортируйте весь список из другого модуля и обратитесь к ним как
PDF_TYPES.report
к etc. Словарь был быimport PDF_TYPES, REPORT; PDF_TYPES[REPORT]
, т. е. 2 импорта для доступа к одному значению-это нехорошо. - В виде списка, например
if x not in PDF_TYPES: raise ValueError(....)
.
Я посмотрел на классы данных, но они, похоже, предназначены для экземпляров вещей, это константы. Словарь был бы идеальным, если бы не неуклюжесть в scneario 2, в нем нет поиска атрибутов. Каков наиболее простой способ достижения вышеуказанных 3 требований?
Комментарии:
1. Использовать перечисление? docs.python.org/3/library/enum.html
2. Вероятно, вам просто нужно перечисление, но обратите внимание , что, вероятно,
__iter__
должно быть что-то вродеyield self.summary; yield self.report
того, что вы имели в видуiter([self.summary, self.report])
3. @juanpa.arrivillaga спасибо за это, но это метод класса, поэтому в нем нет «я».
4. @run_the_race что?
5. @juanpa.arrivillaga ваше решение
self.summary
включает в себя словоself
, ноPDF_TYPES
не предназначено для создания экземпляра.
Ответ №1:
Похоже, перечисление-это то, что вы описываете
from enum import Enum
class PDF_TYPES(Enum):
summary = 'summary'
report = 'report'
тогда, например
>>> PDF_TYPES.summary
<PDF_TYPES.summary: 'summary'>
>>> for pdf_type in PDF_TYPES:
print(pdf_type)
PDF_TYPES.summary
PDF_TYPES.report
В каждой записи перечисления есть .name
и .value
, поэтому, если вы хотите проверить наличие содержимого, вы можете использовать any
>>> any('report' == pdf_type.value for pdf_type in PDF_TYPES)
True
>>> any('foobar' == pdf_type.value for pdf_type in PDF_TYPES)
False
Комментарии:
1. Отлично, за исключением того, что нельзя проверить, скажем,
'report' in PDF_TYPES
2. @run_the_race Я обновил свой ответ, чтобы решить эту проблему. Хотя это не так просто, как использовать
in
, вы могли бы достичь этого с помощьюany
.