A common idiom I have is something like this: (the iterator doesnt work btw):
SUMMARY = 'summary' REPORT = 'report' class PDF_TYPES: summary = SUMMARY report = REPORT class __metaclass__(type): def __iter__(self): return iter(list(self.summary, self.report))
Firstly thats a lot of boilerplate for 2 values.
I would like to define some constants in a list and be able to:
- Refer to them individiually, e.g.
- Import the whole list from another module, and refer to them as
PDF_TYPES.reportetc. A dictionary would be
import PDF_TYPES, REPORT; PDF_TYPES[REPORT], i.e. 2 imports to access one value is not nice.
- As a list, e.g.
if x not in PDF_TYPES: raise ValueError(....).
I looked at dataclasses but they seem to be for instances of things, these are constants. A dictionary would be perfect except for the clunkiness in scneario 2, it doesnt have the attribute look up. What is the most pythonic way of achieving above 3 requirements?
Seems like an enum is what you’re describing
from enum import Enum class PDF_TYPES(Enum): summary = 'summary' report = 'report'
then for example
>>> PDF_TYPES.summary <PDF_TYPES.summary: 'summary'> >>> for pdf_type in PDF_TYPES: print(pdf_type) PDF_TYPES.summary PDF_TYPES.report
Every enum entry has a
.value so if you want to check for containment you could use
>>> any('report' == pdf_type.value for pdf_type in PDF_TYPES) True >>> any('foobar' == pdf_type.value for pdf_type in PDF_TYPES) False