17db96d56Sopenharmony_ci========== 27db96d56Sopenharmony_ciEnum HOWTO 37db96d56Sopenharmony_ci========== 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci.. _enum-basic-tutorial: 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci.. currentmodule:: enum 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ciAn :class:`Enum` is a set of symbolic names bound to unique values. They are 107db96d56Sopenharmony_cisimilar to global variables, but they offer a more useful :func:`repr()`, 117db96d56Sopenharmony_cigrouping, type-safety, and a few other features. 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ciThey are most useful when you have a variable that can take one of a limited 147db96d56Sopenharmony_ciselection of values. For example, the days of the week:: 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci >>> from enum import Enum 177db96d56Sopenharmony_ci >>> class Weekday(Enum): 187db96d56Sopenharmony_ci ... MONDAY = 1 197db96d56Sopenharmony_ci ... TUESDAY = 2 207db96d56Sopenharmony_ci ... WEDNESDAY = 3 217db96d56Sopenharmony_ci ... THURSDAY = 4 227db96d56Sopenharmony_ci ... FRIDAY = 5 237db96d56Sopenharmony_ci ... SATURDAY = 6 247db96d56Sopenharmony_ci ... SUNDAY = 7 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ciOr perhaps the RGB primary colors:: 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci >>> from enum import Enum 297db96d56Sopenharmony_ci >>> class Color(Enum): 307db96d56Sopenharmony_ci ... RED = 1 317db96d56Sopenharmony_ci ... GREEN = 2 327db96d56Sopenharmony_ci ... BLUE = 3 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ciAs you can see, creating an :class:`Enum` is as simple as writing a class that 357db96d56Sopenharmony_ciinherits from :class:`Enum` itself. 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci.. note:: Case of Enum Members 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci Because Enums are used to represent constants we recommend using 407db96d56Sopenharmony_ci UPPER_CASE names for members, and will be using that style in our examples. 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ciDepending on the nature of the enum a member's value may or may not be 437db96d56Sopenharmony_ciimportant, but either way that value can be used to get the corresponding 447db96d56Sopenharmony_cimember:: 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci >>> Weekday(3) 477db96d56Sopenharmony_ci <Weekday.WEDNESDAY: 3> 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ciAs you can see, the ``repr()`` of a member shows the enum name, the member name, 507db96d56Sopenharmony_ciand the value. The ``str()`` of a member shows only the enum name and member 517db96d56Sopenharmony_ciname:: 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci >>> print(Weekday.THURSDAY) 547db96d56Sopenharmony_ci Weekday.THURSDAY 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ciThe *type* of an enumeration member is the enum it belongs to:: 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci >>> type(Weekday.MONDAY) 597db96d56Sopenharmony_ci <enum 'Weekday'> 607db96d56Sopenharmony_ci >>> isinstance(Weekday.FRIDAY, Weekday) 617db96d56Sopenharmony_ci True 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ciEnum members have an attribute that contains just their :attr:`name`:: 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci >>> print(Weekday.TUESDAY.name) 667db96d56Sopenharmony_ci TUESDAY 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ciLikewise, they have an attribute for their :attr:`value`:: 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci >>> Weekday.WEDNESDAY.value 727db96d56Sopenharmony_ci 3 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ciUnlike many languages that treat enumerations solely as name/value pairs, 757db96d56Sopenharmony_ciPython Enums can have behavior added. For example, :class:`datetime.date` 767db96d56Sopenharmony_cihas two methods for returning the weekday: :meth:`weekday` and :meth:`isoweekday`. 777db96d56Sopenharmony_ciThe difference is that one of them counts from 0-6 and the other from 1-7. 787db96d56Sopenharmony_ciRather than keep track of that ourselves we can add a method to the :class:`Weekday` 797db96d56Sopenharmony_cienum to extract the day from the :class:`date` instance and return the matching 807db96d56Sopenharmony_cienum member:: 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci @classmethod 837db96d56Sopenharmony_ci def from_date(cls, date): 847db96d56Sopenharmony_ci return cls(date.isoweekday()) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ciThe complete :class:`Weekday` enum now looks like this:: 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci >>> class Weekday(Enum): 897db96d56Sopenharmony_ci ... MONDAY = 1 907db96d56Sopenharmony_ci ... TUESDAY = 2 917db96d56Sopenharmony_ci ... WEDNESDAY = 3 927db96d56Sopenharmony_ci ... THURSDAY = 4 937db96d56Sopenharmony_ci ... FRIDAY = 5 947db96d56Sopenharmony_ci ... SATURDAY = 6 957db96d56Sopenharmony_ci ... SUNDAY = 7 967db96d56Sopenharmony_ci ... # 977db96d56Sopenharmony_ci ... @classmethod 987db96d56Sopenharmony_ci ... def from_date(cls, date): 997db96d56Sopenharmony_ci ... return cls(date.isoweekday()) 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ciNow we can find out what today is! Observe:: 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci >>> from datetime import date 1047db96d56Sopenharmony_ci >>> Weekday.from_date(date.today()) # doctest: +SKIP 1057db96d56Sopenharmony_ci <Weekday.TUESDAY: 2> 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ciOf course, if you're reading this on some other day, you'll see that day instead. 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ciThis :class:`Weekday` enum is great if our variable only needs one day, but 1107db96d56Sopenharmony_ciwhat if we need several? Maybe we're writing a function to plot chores during 1117db96d56Sopenharmony_cia week, and don't want to use a :class:`list` -- we could use a different type 1127db96d56Sopenharmony_ciof :class:`Enum`:: 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci >>> from enum import Flag 1157db96d56Sopenharmony_ci >>> class Weekday(Flag): 1167db96d56Sopenharmony_ci ... MONDAY = 1 1177db96d56Sopenharmony_ci ... TUESDAY = 2 1187db96d56Sopenharmony_ci ... WEDNESDAY = 4 1197db96d56Sopenharmony_ci ... THURSDAY = 8 1207db96d56Sopenharmony_ci ... FRIDAY = 16 1217db96d56Sopenharmony_ci ... SATURDAY = 32 1227db96d56Sopenharmony_ci ... SUNDAY = 64 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ciWe've changed two things: we're inherited from :class:`Flag`, and the values are 1257db96d56Sopenharmony_ciall powers of 2. 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ciJust like the original :class:`Weekday` enum above, we can have a single selection:: 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci >>> first_week_day = Weekday.MONDAY 1307db96d56Sopenharmony_ci >>> first_week_day 1317db96d56Sopenharmony_ci <Weekday.MONDAY: 1> 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ciBut :class:`Flag` also allows us to combine several members into a single 1347db96d56Sopenharmony_civariable:: 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY 1377db96d56Sopenharmony_ci >>> weekend 1387db96d56Sopenharmony_ci <Weekday.SATURDAY|SUNDAY: 96> 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ciYou can even iterate over a :class:`Flag` variable:: 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci >>> for day in weekend: 1437db96d56Sopenharmony_ci ... print(day) 1447db96d56Sopenharmony_ci Weekday.SATURDAY 1457db96d56Sopenharmony_ci Weekday.SUNDAY 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ciOkay, let's get some chores set up:: 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci >>> chores_for_ethan = { 1507db96d56Sopenharmony_ci ... 'feed the cat': Weekday.MONDAY | Weekday.WEDNESDAY | Weekday.FRIDAY, 1517db96d56Sopenharmony_ci ... 'do the dishes': Weekday.TUESDAY | Weekday.THURSDAY, 1527db96d56Sopenharmony_ci ... 'answer SO questions': Weekday.SATURDAY, 1537db96d56Sopenharmony_ci ... } 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ciAnd a function to display the chores for a given day:: 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci >>> def show_chores(chores, day): 1587db96d56Sopenharmony_ci ... for chore, days in chores.items(): 1597db96d56Sopenharmony_ci ... if day in days: 1607db96d56Sopenharmony_ci ... print(chore) 1617db96d56Sopenharmony_ci >>> show_chores(chores_for_ethan, Weekday.SATURDAY) 1627db96d56Sopenharmony_ci answer SO questions 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ciIn cases where the actual values of the members do not matter, you can save 1657db96d56Sopenharmony_ciyourself some work and use :func:`auto()` for the values:: 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci >>> from enum import auto 1687db96d56Sopenharmony_ci >>> class Weekday(Flag): 1697db96d56Sopenharmony_ci ... MONDAY = auto() 1707db96d56Sopenharmony_ci ... TUESDAY = auto() 1717db96d56Sopenharmony_ci ... WEDNESDAY = auto() 1727db96d56Sopenharmony_ci ... THURSDAY = auto() 1737db96d56Sopenharmony_ci ... FRIDAY = auto() 1747db96d56Sopenharmony_ci ... SATURDAY = auto() 1757db96d56Sopenharmony_ci ... SUNDAY = auto() 1767db96d56Sopenharmony_ci ... WEEKEND = SATURDAY | SUNDAY 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci.. _enum-advanced-tutorial: 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ciProgrammatic access to enumeration members and their attributes 1837db96d56Sopenharmony_ci--------------------------------------------------------------- 1847db96d56Sopenharmony_ci 1857db96d56Sopenharmony_ciSometimes it's useful to access members in enumerations programmatically (i.e. 1867db96d56Sopenharmony_cisituations where ``Color.RED`` won't do because the exact color is not known 1877db96d56Sopenharmony_ciat program-writing time). ``Enum`` allows such access:: 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci >>> Color(1) 1907db96d56Sopenharmony_ci <Color.RED: 1> 1917db96d56Sopenharmony_ci >>> Color(3) 1927db96d56Sopenharmony_ci <Color.BLUE: 3> 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ciIf you want to access enum members by *name*, use item access:: 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci >>> Color['RED'] 1977db96d56Sopenharmony_ci <Color.RED: 1> 1987db96d56Sopenharmony_ci >>> Color['GREEN'] 1997db96d56Sopenharmony_ci <Color.GREEN: 2> 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ciIf you have an enum member and need its :attr:`name` or :attr:`value`:: 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci >>> member = Color.RED 2047db96d56Sopenharmony_ci >>> member.name 2057db96d56Sopenharmony_ci 'RED' 2067db96d56Sopenharmony_ci >>> member.value 2077db96d56Sopenharmony_ci 1 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ciDuplicating enum members and values 2117db96d56Sopenharmony_ci----------------------------------- 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ciHaving two enum members with the same name is invalid:: 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci >>> class Shape(Enum): 2167db96d56Sopenharmony_ci ... SQUARE = 2 2177db96d56Sopenharmony_ci ... SQUARE = 3 2187db96d56Sopenharmony_ci ... 2197db96d56Sopenharmony_ci Traceback (most recent call last): 2207db96d56Sopenharmony_ci ... 2217db96d56Sopenharmony_ci TypeError: 'SQUARE' already defined as 2 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ciHowever, an enum member can have other names associated with it. Given two 2247db96d56Sopenharmony_cientries ``A`` and ``B`` with the same value (and ``A`` defined first), ``B`` 2257db96d56Sopenharmony_ciis an alias for the member ``A``. By-value lookup of the value of ``A`` will 2267db96d56Sopenharmony_cireturn the member ``A``. By-name lookup of ``A`` will return the member ``A``. 2277db96d56Sopenharmony_ciBy-name lookup of ``B`` will also return the member ``A``:: 2287db96d56Sopenharmony_ci 2297db96d56Sopenharmony_ci >>> class Shape(Enum): 2307db96d56Sopenharmony_ci ... SQUARE = 2 2317db96d56Sopenharmony_ci ... DIAMOND = 1 2327db96d56Sopenharmony_ci ... CIRCLE = 3 2337db96d56Sopenharmony_ci ... ALIAS_FOR_SQUARE = 2 2347db96d56Sopenharmony_ci ... 2357db96d56Sopenharmony_ci >>> Shape.SQUARE 2367db96d56Sopenharmony_ci <Shape.SQUARE: 2> 2377db96d56Sopenharmony_ci >>> Shape.ALIAS_FOR_SQUARE 2387db96d56Sopenharmony_ci <Shape.SQUARE: 2> 2397db96d56Sopenharmony_ci >>> Shape(2) 2407db96d56Sopenharmony_ci <Shape.SQUARE: 2> 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci.. note:: 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci Attempting to create a member with the same name as an already 2457db96d56Sopenharmony_ci defined attribute (another member, a method, etc.) or attempting to create 2467db96d56Sopenharmony_ci an attribute with the same name as a member is not allowed. 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ciEnsuring unique enumeration values 2507db96d56Sopenharmony_ci---------------------------------- 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ciBy default, enumerations allow multiple names as aliases for the same value. 2537db96d56Sopenharmony_ciWhen this behavior isn't desired, you can use the :func:`unique` decorator:: 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci >>> from enum import Enum, unique 2567db96d56Sopenharmony_ci >>> @unique 2577db96d56Sopenharmony_ci ... class Mistake(Enum): 2587db96d56Sopenharmony_ci ... ONE = 1 2597db96d56Sopenharmony_ci ... TWO = 2 2607db96d56Sopenharmony_ci ... THREE = 3 2617db96d56Sopenharmony_ci ... FOUR = 3 2627db96d56Sopenharmony_ci ... 2637db96d56Sopenharmony_ci Traceback (most recent call last): 2647db96d56Sopenharmony_ci ... 2657db96d56Sopenharmony_ci ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ciUsing automatic values 2697db96d56Sopenharmony_ci---------------------- 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ciIf the exact value is unimportant you can use :class:`auto`:: 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ci >>> from enum import Enum, auto 2747db96d56Sopenharmony_ci >>> class Color(Enum): 2757db96d56Sopenharmony_ci ... RED = auto() 2767db96d56Sopenharmony_ci ... BLUE = auto() 2777db96d56Sopenharmony_ci ... GREEN = auto() 2787db96d56Sopenharmony_ci ... 2797db96d56Sopenharmony_ci >>> [member.value for member in Color] 2807db96d56Sopenharmony_ci [1, 2, 3] 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ciThe values are chosen by :func:`_generate_next_value_`, which can be 2837db96d56Sopenharmony_cioverridden:: 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_ci >>> class AutoName(Enum): 2867db96d56Sopenharmony_ci ... def _generate_next_value_(name, start, count, last_values): 2877db96d56Sopenharmony_ci ... return name 2887db96d56Sopenharmony_ci ... 2897db96d56Sopenharmony_ci >>> class Ordinal(AutoName): 2907db96d56Sopenharmony_ci ... NORTH = auto() 2917db96d56Sopenharmony_ci ... SOUTH = auto() 2927db96d56Sopenharmony_ci ... EAST = auto() 2937db96d56Sopenharmony_ci ... WEST = auto() 2947db96d56Sopenharmony_ci ... 2957db96d56Sopenharmony_ci >>> [member.value for member in Ordinal] 2967db96d56Sopenharmony_ci ['NORTH', 'SOUTH', 'EAST', 'WEST'] 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci.. note:: 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci The :meth:`_generate_next_value_` method must be defined before any members. 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ciIteration 3037db96d56Sopenharmony_ci--------- 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ciIterating over the members of an enum does not provide the aliases:: 3067db96d56Sopenharmony_ci 3077db96d56Sopenharmony_ci >>> list(Shape) 3087db96d56Sopenharmony_ci [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>] 3097db96d56Sopenharmony_ci >>> list(Weekday) 3107db96d56Sopenharmony_ci [<Weekday.MONDAY: 1>, <Weekday.TUESDAY: 2>, <Weekday.WEDNESDAY: 4>, <Weekday.THURSDAY: 8>, <Weekday.FRIDAY: 16>, <Weekday.SATURDAY: 32>, <Weekday.SUNDAY: 64>] 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ciNote that the aliases ``Shape.ALIAS_FOR_SQUARE`` and ``Weekday.WEEKEND`` aren't shown. 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ciThe special attribute ``__members__`` is a read-only ordered mapping of names 3157db96d56Sopenharmony_cito members. It includes all names defined in the enumeration, including the 3167db96d56Sopenharmony_cialiases:: 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci >>> for name, member in Shape.__members__.items(): 3197db96d56Sopenharmony_ci ... name, member 3207db96d56Sopenharmony_ci ... 3217db96d56Sopenharmony_ci ('SQUARE', <Shape.SQUARE: 2>) 3227db96d56Sopenharmony_ci ('DIAMOND', <Shape.DIAMOND: 1>) 3237db96d56Sopenharmony_ci ('CIRCLE', <Shape.CIRCLE: 3>) 3247db96d56Sopenharmony_ci ('ALIAS_FOR_SQUARE', <Shape.SQUARE: 2>) 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ciThe ``__members__`` attribute can be used for detailed programmatic access to 3277db96d56Sopenharmony_cithe enumeration members. For example, finding all the aliases:: 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci >>> [name for name, member in Shape.__members__.items() if member.name != name] 3307db96d56Sopenharmony_ci ['ALIAS_FOR_SQUARE'] 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci.. note:: 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci Aliases for flags include values with multiple flags set, such as ``3``, 3357db96d56Sopenharmony_ci and no flags set, i.e. ``0``. 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ciComparisons 3397db96d56Sopenharmony_ci----------- 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ciEnumeration members are compared by identity:: 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci >>> Color.RED is Color.RED 3447db96d56Sopenharmony_ci True 3457db96d56Sopenharmony_ci >>> Color.RED is Color.BLUE 3467db96d56Sopenharmony_ci False 3477db96d56Sopenharmony_ci >>> Color.RED is not Color.BLUE 3487db96d56Sopenharmony_ci True 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ciOrdered comparisons between enumeration values are *not* supported. Enum 3517db96d56Sopenharmony_cimembers are not integers (but see `IntEnum`_ below):: 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci >>> Color.RED < Color.BLUE 3547db96d56Sopenharmony_ci Traceback (most recent call last): 3557db96d56Sopenharmony_ci File "<stdin>", line 1, in <module> 3567db96d56Sopenharmony_ci TypeError: '<' not supported between instances of 'Color' and 'Color' 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ciEquality comparisons are defined though:: 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci >>> Color.BLUE == Color.RED 3617db96d56Sopenharmony_ci False 3627db96d56Sopenharmony_ci >>> Color.BLUE != Color.RED 3637db96d56Sopenharmony_ci True 3647db96d56Sopenharmony_ci >>> Color.BLUE == Color.BLUE 3657db96d56Sopenharmony_ci True 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ciComparisons against non-enumeration values will always compare not equal 3687db96d56Sopenharmony_ci(again, :class:`IntEnum` was explicitly designed to behave differently, see 3697db96d56Sopenharmony_cibelow):: 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci >>> Color.BLUE == 2 3727db96d56Sopenharmony_ci False 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci.. warning:: 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ci It is possible to reload modules -- if a reloaded module contains 3777db96d56Sopenharmony_ci enums, they will be recreated, and the new members may not 3787db96d56Sopenharmony_ci compare identical/equal to the original members. 3797db96d56Sopenharmony_ci 3807db96d56Sopenharmony_ciAllowed members and attributes of enumerations 3817db96d56Sopenharmony_ci---------------------------------------------- 3827db96d56Sopenharmony_ci 3837db96d56Sopenharmony_ciMost of the examples above use integers for enumeration values. Using integers 3847db96d56Sopenharmony_ciis short and handy (and provided by default by the `Functional API`_), but not 3857db96d56Sopenharmony_cistrictly enforced. In the vast majority of use-cases, one doesn't care what 3867db96d56Sopenharmony_cithe actual value of an enumeration is. But if the value *is* important, 3877db96d56Sopenharmony_cienumerations can have arbitrary values. 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_ciEnumerations are Python classes, and can have methods and special methods as 3907db96d56Sopenharmony_ciusual. If we have this enumeration:: 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ci >>> class Mood(Enum): 3937db96d56Sopenharmony_ci ... FUNKY = 1 3947db96d56Sopenharmony_ci ... HAPPY = 3 3957db96d56Sopenharmony_ci ... 3967db96d56Sopenharmony_ci ... def describe(self): 3977db96d56Sopenharmony_ci ... # self is the member here 3987db96d56Sopenharmony_ci ... return self.name, self.value 3997db96d56Sopenharmony_ci ... 4007db96d56Sopenharmony_ci ... def __str__(self): 4017db96d56Sopenharmony_ci ... return 'my custom str! {0}'.format(self.value) 4027db96d56Sopenharmony_ci ... 4037db96d56Sopenharmony_ci ... @classmethod 4047db96d56Sopenharmony_ci ... def favorite_mood(cls): 4057db96d56Sopenharmony_ci ... # cls here is the enumeration 4067db96d56Sopenharmony_ci ... return cls.HAPPY 4077db96d56Sopenharmony_ci ... 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_ciThen:: 4107db96d56Sopenharmony_ci 4117db96d56Sopenharmony_ci >>> Mood.favorite_mood() 4127db96d56Sopenharmony_ci <Mood.HAPPY: 3> 4137db96d56Sopenharmony_ci >>> Mood.HAPPY.describe() 4147db96d56Sopenharmony_ci ('HAPPY', 3) 4157db96d56Sopenharmony_ci >>> str(Mood.FUNKY) 4167db96d56Sopenharmony_ci 'my custom str! 1' 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ciThe rules for what is allowed are as follows: names that start and end with 4197db96d56Sopenharmony_cia single underscore are reserved by enum and cannot be used; all other 4207db96d56Sopenharmony_ciattributes defined within an enumeration will become members of this 4217db96d56Sopenharmony_cienumeration, with the exception of special methods (:meth:`__str__`, 4227db96d56Sopenharmony_ci:meth:`__add__`, etc.), descriptors (methods are also descriptors), and 4237db96d56Sopenharmony_civariable names listed in :attr:`_ignore_`. 4247db96d56Sopenharmony_ci 4257db96d56Sopenharmony_ciNote: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then 4267db96d56Sopenharmony_ciany value(s) given to the enum member will be passed into those methods. 4277db96d56Sopenharmony_ciSee `Planet`_ for an example. 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ciRestricted Enum subclassing 4317db96d56Sopenharmony_ci--------------------------- 4327db96d56Sopenharmony_ci 4337db96d56Sopenharmony_ciA new :class:`Enum` class must have one base enum class, up to one concrete 4347db96d56Sopenharmony_cidata type, and as many :class:`object`-based mixin classes as needed. The 4357db96d56Sopenharmony_ciorder of these base classes is:: 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_ci class EnumName([mix-in, ...,] [data-type,] base-enum): 4387db96d56Sopenharmony_ci pass 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ciAlso, subclassing an enumeration is allowed only if the enumeration does not define 4417db96d56Sopenharmony_ciany members. So this is forbidden:: 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci >>> class MoreColor(Color): 4447db96d56Sopenharmony_ci ... PINK = 17 4457db96d56Sopenharmony_ci ... 4467db96d56Sopenharmony_ci Traceback (most recent call last): 4477db96d56Sopenharmony_ci ... 4487db96d56Sopenharmony_ci TypeError: <enum 'MoreColor'> cannot extend <enum 'Color'> 4497db96d56Sopenharmony_ci 4507db96d56Sopenharmony_ciBut this is allowed:: 4517db96d56Sopenharmony_ci 4527db96d56Sopenharmony_ci >>> class Foo(Enum): 4537db96d56Sopenharmony_ci ... def some_behavior(self): 4547db96d56Sopenharmony_ci ... pass 4557db96d56Sopenharmony_ci ... 4567db96d56Sopenharmony_ci >>> class Bar(Foo): 4577db96d56Sopenharmony_ci ... HAPPY = 1 4587db96d56Sopenharmony_ci ... SAD = 2 4597db96d56Sopenharmony_ci ... 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ciAllowing subclassing of enums that define members would lead to a violation of 4627db96d56Sopenharmony_cisome important invariants of types and instances. On the other hand, it makes 4637db96d56Sopenharmony_cisense to allow sharing some common behavior between a group of enumerations. 4647db96d56Sopenharmony_ci(See `OrderedEnum`_ for an example.) 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ciPickling 4687db96d56Sopenharmony_ci-------- 4697db96d56Sopenharmony_ci 4707db96d56Sopenharmony_ciEnumerations can be pickled and unpickled:: 4717db96d56Sopenharmony_ci 4727db96d56Sopenharmony_ci >>> from test.test_enum import Fruit 4737db96d56Sopenharmony_ci >>> from pickle import dumps, loads 4747db96d56Sopenharmony_ci >>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO)) 4757db96d56Sopenharmony_ci True 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ciThe usual restrictions for pickling apply: picklable enums must be defined in 4787db96d56Sopenharmony_cithe top level of a module, since unpickling requires them to be importable 4797db96d56Sopenharmony_cifrom that module. 4807db96d56Sopenharmony_ci 4817db96d56Sopenharmony_ci.. note:: 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_ci With pickle protocol version 4 it is possible to easily pickle enums 4847db96d56Sopenharmony_ci nested in other classes. 4857db96d56Sopenharmony_ci 4867db96d56Sopenharmony_ciIt is possible to modify how enum members are pickled/unpickled by defining 4877db96d56Sopenharmony_ci:meth:`__reduce_ex__` in the enumeration class. 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_ci 4907db96d56Sopenharmony_ciFunctional API 4917db96d56Sopenharmony_ci-------------- 4927db96d56Sopenharmony_ci 4937db96d56Sopenharmony_ciThe :class:`Enum` class is callable, providing the following functional API:: 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_ci >>> Animal = Enum('Animal', 'ANT BEE CAT DOG') 4967db96d56Sopenharmony_ci >>> Animal 4977db96d56Sopenharmony_ci <enum 'Animal'> 4987db96d56Sopenharmony_ci >>> Animal.ANT 4997db96d56Sopenharmony_ci <Animal.ANT: 1> 5007db96d56Sopenharmony_ci >>> list(Animal) 5017db96d56Sopenharmony_ci [<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>] 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ciThe semantics of this API resemble :class:`~collections.namedtuple`. The first 5047db96d56Sopenharmony_ciargument of the call to :class:`Enum` is the name of the enumeration. 5057db96d56Sopenharmony_ci 5067db96d56Sopenharmony_ciThe second argument is the *source* of enumeration member names. It can be a 5077db96d56Sopenharmony_ciwhitespace-separated string of names, a sequence of names, a sequence of 5087db96d56Sopenharmony_ci2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to 5097db96d56Sopenharmony_civalues. The last two options enable assigning arbitrary values to 5107db96d56Sopenharmony_cienumerations; the others auto-assign increasing integers starting with 1 (use 5117db96d56Sopenharmony_cithe ``start`` parameter to specify a different starting value). A 5127db96d56Sopenharmony_cinew class derived from :class:`Enum` is returned. In other words, the above 5137db96d56Sopenharmony_ciassignment to :class:`Animal` is equivalent to:: 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci >>> class Animal(Enum): 5167db96d56Sopenharmony_ci ... ANT = 1 5177db96d56Sopenharmony_ci ... BEE = 2 5187db96d56Sopenharmony_ci ... CAT = 3 5197db96d56Sopenharmony_ci ... DOG = 4 5207db96d56Sopenharmony_ci ... 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ciThe reason for defaulting to ``1`` as the starting number and not ``0`` is 5237db96d56Sopenharmony_cithat ``0`` is ``False`` in a boolean sense, but by default enum members all 5247db96d56Sopenharmony_cievaluate to ``True``. 5257db96d56Sopenharmony_ci 5267db96d56Sopenharmony_ciPickling enums created with the functional API can be tricky as frame stack 5277db96d56Sopenharmony_ciimplementation details are used to try and figure out which module the 5287db96d56Sopenharmony_cienumeration is being created in (e.g. it will fail if you use a utility 5297db96d56Sopenharmony_cifunction in a separate module, and also may not work on IronPython or Jython). 5307db96d56Sopenharmony_ciThe solution is to specify the module name explicitly as follows:: 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__) 5337db96d56Sopenharmony_ci 5347db96d56Sopenharmony_ci.. warning:: 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci If ``module`` is not supplied, and Enum cannot determine what it is, 5377db96d56Sopenharmony_ci the new Enum members will not be unpicklable; to keep errors closer to 5387db96d56Sopenharmony_ci the source, pickling will be disabled. 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ciThe new pickle protocol 4 also, in some circumstances, relies on 5417db96d56Sopenharmony_ci:attr:`~definition.__qualname__` being set to the location where pickle will be able 5427db96d56Sopenharmony_cito find the class. For example, if the class was made available in class 5437db96d56Sopenharmony_ciSomeData in the global scope:: 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal') 5467db96d56Sopenharmony_ci 5477db96d56Sopenharmony_ciThe complete signature is:: 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci Enum( 5507db96d56Sopenharmony_ci value='NewEnumName', 5517db96d56Sopenharmony_ci names=<...>, 5527db96d56Sopenharmony_ci *, 5537db96d56Sopenharmony_ci module='...', 5547db96d56Sopenharmony_ci qualname='...', 5557db96d56Sopenharmony_ci type=<mixed-in class>, 5567db96d56Sopenharmony_ci start=1, 5577db96d56Sopenharmony_ci ) 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_ci:value: What the new enum class will record as its name. 5607db96d56Sopenharmony_ci 5617db96d56Sopenharmony_ci:names: The enum members. This can be a whitespace- or comma-separated string 5627db96d56Sopenharmony_ci (values will start at 1 unless otherwise specified):: 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_ci 'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE' 5657db96d56Sopenharmony_ci 5667db96d56Sopenharmony_ci or an iterator of names:: 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_ci ['RED', 'GREEN', 'BLUE'] 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci or an iterator of (name, value) pairs:: 5717db96d56Sopenharmony_ci 5727db96d56Sopenharmony_ci [('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)] 5737db96d56Sopenharmony_ci 5747db96d56Sopenharmony_ci or a mapping:: 5757db96d56Sopenharmony_ci 5767db96d56Sopenharmony_ci {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42} 5777db96d56Sopenharmony_ci 5787db96d56Sopenharmony_ci:module: name of module where new enum class can be found. 5797db96d56Sopenharmony_ci 5807db96d56Sopenharmony_ci:qualname: where in module new enum class can be found. 5817db96d56Sopenharmony_ci 5827db96d56Sopenharmony_ci:type: type to mix in to new enum class. 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_ci:start: number to start counting at if only names are passed in. 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_ci.. versionchanged:: 3.5 5877db96d56Sopenharmony_ci The *start* parameter was added. 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_ciDerived Enumerations 5917db96d56Sopenharmony_ci-------------------- 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ciIntEnum 5947db96d56Sopenharmony_ci^^^^^^^ 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_ciThe first variation of :class:`Enum` that is provided is also a subclass of 5977db96d56Sopenharmony_ci:class:`int`. Members of an :class:`IntEnum` can be compared to integers; 5987db96d56Sopenharmony_ciby extension, integer enumerations of different types can also be compared 5997db96d56Sopenharmony_cito each other:: 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ci >>> from enum import IntEnum 6027db96d56Sopenharmony_ci >>> class Shape(IntEnum): 6037db96d56Sopenharmony_ci ... CIRCLE = 1 6047db96d56Sopenharmony_ci ... SQUARE = 2 6057db96d56Sopenharmony_ci ... 6067db96d56Sopenharmony_ci >>> class Request(IntEnum): 6077db96d56Sopenharmony_ci ... POST = 1 6087db96d56Sopenharmony_ci ... GET = 2 6097db96d56Sopenharmony_ci ... 6107db96d56Sopenharmony_ci >>> Shape == 1 6117db96d56Sopenharmony_ci False 6127db96d56Sopenharmony_ci >>> Shape.CIRCLE == 1 6137db96d56Sopenharmony_ci True 6147db96d56Sopenharmony_ci >>> Shape.CIRCLE == Request.POST 6157db96d56Sopenharmony_ci True 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ciHowever, they still can't be compared to standard :class:`Enum` enumerations:: 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_ci >>> class Shape(IntEnum): 6207db96d56Sopenharmony_ci ... CIRCLE = 1 6217db96d56Sopenharmony_ci ... SQUARE = 2 6227db96d56Sopenharmony_ci ... 6237db96d56Sopenharmony_ci >>> class Color(Enum): 6247db96d56Sopenharmony_ci ... RED = 1 6257db96d56Sopenharmony_ci ... GREEN = 2 6267db96d56Sopenharmony_ci ... 6277db96d56Sopenharmony_ci >>> Shape.CIRCLE == Color.RED 6287db96d56Sopenharmony_ci False 6297db96d56Sopenharmony_ci 6307db96d56Sopenharmony_ci:class:`IntEnum` values behave like integers in other ways you'd expect:: 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_ci >>> int(Shape.CIRCLE) 6337db96d56Sopenharmony_ci 1 6347db96d56Sopenharmony_ci >>> ['a', 'b', 'c'][Shape.CIRCLE] 6357db96d56Sopenharmony_ci 'b' 6367db96d56Sopenharmony_ci >>> [i for i in range(Shape.SQUARE)] 6377db96d56Sopenharmony_ci [0, 1] 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_ci 6407db96d56Sopenharmony_ciStrEnum 6417db96d56Sopenharmony_ci^^^^^^^ 6427db96d56Sopenharmony_ci 6437db96d56Sopenharmony_ciThe second variation of :class:`Enum` that is provided is also a subclass of 6447db96d56Sopenharmony_ci:class:`str`. Members of a :class:`StrEnum` can be compared to strings; 6457db96d56Sopenharmony_ciby extension, string enumerations of different types can also be compared 6467db96d56Sopenharmony_cito each other. 6477db96d56Sopenharmony_ci 6487db96d56Sopenharmony_ci.. versionadded:: 3.11 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ciIntFlag 6527db96d56Sopenharmony_ci^^^^^^^ 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_ciThe next variation of :class:`Enum` provided, :class:`IntFlag`, is also based 6557db96d56Sopenharmony_cion :class:`int`. The difference being :class:`IntFlag` members can be combined 6567db96d56Sopenharmony_ciusing the bitwise operators (&, \|, ^, ~) and the result is still an 6577db96d56Sopenharmony_ci:class:`IntFlag` member, if possible. Like :class:`IntEnum`, :class:`IntFlag` 6587db96d56Sopenharmony_cimembers are also integers and can be used wherever an :class:`int` is used. 6597db96d56Sopenharmony_ci 6607db96d56Sopenharmony_ci.. note:: 6617db96d56Sopenharmony_ci 6627db96d56Sopenharmony_ci Any operation on an :class:`IntFlag` member besides the bit-wise operations will 6637db96d56Sopenharmony_ci lose the :class:`IntFlag` membership. 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_ci Bit-wise operations that result in invalid :class:`IntFlag` values will lose the 6667db96d56Sopenharmony_ci :class:`IntFlag` membership. See :class:`FlagBoundary` for 6677db96d56Sopenharmony_ci details. 6687db96d56Sopenharmony_ci 6697db96d56Sopenharmony_ci.. versionadded:: 3.6 6707db96d56Sopenharmony_ci.. versionchanged:: 3.11 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_ciSample :class:`IntFlag` class:: 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ci >>> from enum import IntFlag 6757db96d56Sopenharmony_ci >>> class Perm(IntFlag): 6767db96d56Sopenharmony_ci ... R = 4 6777db96d56Sopenharmony_ci ... W = 2 6787db96d56Sopenharmony_ci ... X = 1 6797db96d56Sopenharmony_ci ... 6807db96d56Sopenharmony_ci >>> Perm.R | Perm.W 6817db96d56Sopenharmony_ci <Perm.R|W: 6> 6827db96d56Sopenharmony_ci >>> Perm.R + Perm.W 6837db96d56Sopenharmony_ci 6 6847db96d56Sopenharmony_ci >>> RW = Perm.R | Perm.W 6857db96d56Sopenharmony_ci >>> Perm.R in RW 6867db96d56Sopenharmony_ci True 6877db96d56Sopenharmony_ci 6887db96d56Sopenharmony_ciIt is also possible to name the combinations:: 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ci >>> class Perm(IntFlag): 6917db96d56Sopenharmony_ci ... R = 4 6927db96d56Sopenharmony_ci ... W = 2 6937db96d56Sopenharmony_ci ... X = 1 6947db96d56Sopenharmony_ci ... RWX = 7 6957db96d56Sopenharmony_ci >>> Perm.RWX 6967db96d56Sopenharmony_ci <Perm.RWX: 7> 6977db96d56Sopenharmony_ci >>> ~Perm.RWX 6987db96d56Sopenharmony_ci <Perm: 0> 6997db96d56Sopenharmony_ci >>> Perm(7) 7007db96d56Sopenharmony_ci <Perm.RWX: 7> 7017db96d56Sopenharmony_ci 7027db96d56Sopenharmony_ci.. note:: 7037db96d56Sopenharmony_ci 7047db96d56Sopenharmony_ci Named combinations are considered aliases. Aliases do not show up during 7057db96d56Sopenharmony_ci iteration, but can be returned from by-value lookups. 7067db96d56Sopenharmony_ci 7077db96d56Sopenharmony_ci.. versionchanged:: 3.11 7087db96d56Sopenharmony_ci 7097db96d56Sopenharmony_ciAnother important difference between :class:`IntFlag` and :class:`Enum` is that 7107db96d56Sopenharmony_ciif no flags are set (the value is 0), its boolean evaluation is :data:`False`:: 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_ci >>> Perm.R & Perm.X 7137db96d56Sopenharmony_ci <Perm: 0> 7147db96d56Sopenharmony_ci >>> bool(Perm.R & Perm.X) 7157db96d56Sopenharmony_ci False 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_ciBecause :class:`IntFlag` members are also subclasses of :class:`int` they can 7187db96d56Sopenharmony_cibe combined with them (but may lose :class:`IntFlag` membership:: 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_ci >>> Perm.X | 4 7217db96d56Sopenharmony_ci <Perm.R|X: 5> 7227db96d56Sopenharmony_ci 7237db96d56Sopenharmony_ci >>> Perm.X | 8 7247db96d56Sopenharmony_ci 9 7257db96d56Sopenharmony_ci 7267db96d56Sopenharmony_ci.. note:: 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_ci The negation operator, ``~``, always returns an :class:`IntFlag` member with a 7297db96d56Sopenharmony_ci positive value:: 7307db96d56Sopenharmony_ci 7317db96d56Sopenharmony_ci >>> (~Perm.X).value == (Perm.R|Perm.W).value == 6 7327db96d56Sopenharmony_ci True 7337db96d56Sopenharmony_ci 7347db96d56Sopenharmony_ci:class:`IntFlag` members can also be iterated over:: 7357db96d56Sopenharmony_ci 7367db96d56Sopenharmony_ci >>> list(RW) 7377db96d56Sopenharmony_ci [<Perm.R: 4>, <Perm.W: 2>] 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci.. versionadded:: 3.11 7407db96d56Sopenharmony_ci 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ciFlag 7437db96d56Sopenharmony_ci^^^^ 7447db96d56Sopenharmony_ci 7457db96d56Sopenharmony_ciThe last variation is :class:`Flag`. Like :class:`IntFlag`, :class:`Flag` 7467db96d56Sopenharmony_cimembers can be combined using the bitwise operators (&, \|, ^, ~). Unlike 7477db96d56Sopenharmony_ci:class:`IntFlag`, they cannot be combined with, nor compared against, any 7487db96d56Sopenharmony_ciother :class:`Flag` enumeration, nor :class:`int`. While it is possible to 7497db96d56Sopenharmony_cispecify the values directly it is recommended to use :class:`auto` as the 7507db96d56Sopenharmony_civalue and let :class:`Flag` select an appropriate value. 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_ci.. versionadded:: 3.6 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ciLike :class:`IntFlag`, if a combination of :class:`Flag` members results in no 7557db96d56Sopenharmony_ciflags being set, the boolean evaluation is :data:`False`:: 7567db96d56Sopenharmony_ci 7577db96d56Sopenharmony_ci >>> from enum import Flag, auto 7587db96d56Sopenharmony_ci >>> class Color(Flag): 7597db96d56Sopenharmony_ci ... RED = auto() 7607db96d56Sopenharmony_ci ... BLUE = auto() 7617db96d56Sopenharmony_ci ... GREEN = auto() 7627db96d56Sopenharmony_ci ... 7637db96d56Sopenharmony_ci >>> Color.RED & Color.GREEN 7647db96d56Sopenharmony_ci <Color: 0> 7657db96d56Sopenharmony_ci >>> bool(Color.RED & Color.GREEN) 7667db96d56Sopenharmony_ci False 7677db96d56Sopenharmony_ci 7687db96d56Sopenharmony_ciIndividual flags should have values that are powers of two (1, 2, 4, 8, ...), 7697db96d56Sopenharmony_ciwhile combinations of flags will not:: 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_ci >>> class Color(Flag): 7727db96d56Sopenharmony_ci ... RED = auto() 7737db96d56Sopenharmony_ci ... BLUE = auto() 7747db96d56Sopenharmony_ci ... GREEN = auto() 7757db96d56Sopenharmony_ci ... WHITE = RED | BLUE | GREEN 7767db96d56Sopenharmony_ci ... 7777db96d56Sopenharmony_ci >>> Color.WHITE 7787db96d56Sopenharmony_ci <Color.WHITE: 7> 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ciGiving a name to the "no flags set" condition does not change its boolean 7817db96d56Sopenharmony_civalue:: 7827db96d56Sopenharmony_ci 7837db96d56Sopenharmony_ci >>> class Color(Flag): 7847db96d56Sopenharmony_ci ... BLACK = 0 7857db96d56Sopenharmony_ci ... RED = auto() 7867db96d56Sopenharmony_ci ... BLUE = auto() 7877db96d56Sopenharmony_ci ... GREEN = auto() 7887db96d56Sopenharmony_ci ... 7897db96d56Sopenharmony_ci >>> Color.BLACK 7907db96d56Sopenharmony_ci <Color.BLACK: 0> 7917db96d56Sopenharmony_ci >>> bool(Color.BLACK) 7927db96d56Sopenharmony_ci False 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ci:class:`Flag` members can also be iterated over:: 7957db96d56Sopenharmony_ci 7967db96d56Sopenharmony_ci >>> purple = Color.RED | Color.BLUE 7977db96d56Sopenharmony_ci >>> list(purple) 7987db96d56Sopenharmony_ci [<Color.RED: 1>, <Color.BLUE: 2>] 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci.. versionadded:: 3.11 8017db96d56Sopenharmony_ci 8027db96d56Sopenharmony_ci.. note:: 8037db96d56Sopenharmony_ci 8047db96d56Sopenharmony_ci For the majority of new code, :class:`Enum` and :class:`Flag` are strongly 8057db96d56Sopenharmony_ci recommended, since :class:`IntEnum` and :class:`IntFlag` break some 8067db96d56Sopenharmony_ci semantic promises of an enumeration (by being comparable to integers, and 8077db96d56Sopenharmony_ci thus by transitivity to other unrelated enumerations). :class:`IntEnum` 8087db96d56Sopenharmony_ci and :class:`IntFlag` should be used only in cases where :class:`Enum` and 8097db96d56Sopenharmony_ci :class:`Flag` will not do; for example, when integer constants are replaced 8107db96d56Sopenharmony_ci with enumerations, or for interoperability with other systems. 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ciOthers 8147db96d56Sopenharmony_ci^^^^^^ 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ciWhile :class:`IntEnum` is part of the :mod:`enum` module, it would be very 8177db96d56Sopenharmony_cisimple to implement independently:: 8187db96d56Sopenharmony_ci 8197db96d56Sopenharmony_ci class IntEnum(int, Enum): 8207db96d56Sopenharmony_ci pass 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_ciThis demonstrates how similar derived enumerations can be defined; for example 8237db96d56Sopenharmony_cia :class:`FloatEnum` that mixes in :class:`float` instead of :class:`int`. 8247db96d56Sopenharmony_ci 8257db96d56Sopenharmony_ciSome rules: 8267db96d56Sopenharmony_ci 8277db96d56Sopenharmony_ci1. When subclassing :class:`Enum`, mix-in types must appear before 8287db96d56Sopenharmony_ci :class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum` 8297db96d56Sopenharmony_ci example above. 8307db96d56Sopenharmony_ci2. Mix-in types must be subclassable. For example, :class:`bool` and 8317db96d56Sopenharmony_ci :class:`range` are not subclassable and will throw an error during Enum 8327db96d56Sopenharmony_ci creation if used as the mix-in type. 8337db96d56Sopenharmony_ci3. While :class:`Enum` can have members of any type, once you mix in an 8347db96d56Sopenharmony_ci additional type, all the members must have values of that type, e.g. 8357db96d56Sopenharmony_ci :class:`int` above. This restriction does not apply to mix-ins which only 8367db96d56Sopenharmony_ci add methods and don't specify another type. 8377db96d56Sopenharmony_ci4. When another data type is mixed in, the :attr:`value` attribute is *not the 8387db96d56Sopenharmony_ci same* as the enum member itself, although it is equivalent and will compare 8397db96d56Sopenharmony_ci equal. 8407db96d56Sopenharmony_ci5. A ``data type`` is a mixin that defines :meth:`__new__`. 8417db96d56Sopenharmony_ci6. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's 8427db96d56Sopenharmony_ci :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as 8437db96d56Sopenharmony_ci ``%i`` or ``%h`` for IntEnum) treat the enum member as its mixed-in type. 8447db96d56Sopenharmony_ci7. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`, 8457db96d56Sopenharmony_ci and :func:`format` will use the enum's :meth:`__str__` method. 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_ci.. note:: 8487db96d56Sopenharmony_ci 8497db96d56Sopenharmony_ci Because :class:`IntEnum`, :class:`IntFlag`, and :class:`StrEnum` are 8507db96d56Sopenharmony_ci designed to be drop-in replacements for existing constants, their 8517db96d56Sopenharmony_ci :meth:`__str__` method has been reset to their data types' 8527db96d56Sopenharmony_ci :meth:`__str__` method. 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ciWhen to use :meth:`__new__` vs. :meth:`__init__` 8557db96d56Sopenharmony_ci------------------------------------------------ 8567db96d56Sopenharmony_ci 8577db96d56Sopenharmony_ci:meth:`__new__` must be used whenever you want to customize the actual value of 8587db96d56Sopenharmony_cithe :class:`Enum` member. Any other modifications may go in either 8597db96d56Sopenharmony_ci:meth:`__new__` or :meth:`__init__`, with :meth:`__init__` being preferred. 8607db96d56Sopenharmony_ci 8617db96d56Sopenharmony_ciFor example, if you want to pass several items to the constructor, but only 8627db96d56Sopenharmony_ciwant one of them to be the value:: 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_ci >>> class Coordinate(bytes, Enum): 8657db96d56Sopenharmony_ci ... """ 8667db96d56Sopenharmony_ci ... Coordinate with binary codes that can be indexed by the int code. 8677db96d56Sopenharmony_ci ... """ 8687db96d56Sopenharmony_ci ... def __new__(cls, value, label, unit): 8697db96d56Sopenharmony_ci ... obj = bytes.__new__(cls, [value]) 8707db96d56Sopenharmony_ci ... obj._value_ = value 8717db96d56Sopenharmony_ci ... obj.label = label 8727db96d56Sopenharmony_ci ... obj.unit = unit 8737db96d56Sopenharmony_ci ... return obj 8747db96d56Sopenharmony_ci ... PX = (0, 'P.X', 'km') 8757db96d56Sopenharmony_ci ... PY = (1, 'P.Y', 'km') 8767db96d56Sopenharmony_ci ... VX = (2, 'V.X', 'km/s') 8777db96d56Sopenharmony_ci ... VY = (3, 'V.Y', 'km/s') 8787db96d56Sopenharmony_ci ... 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci >>> print(Coordinate['PY']) 8817db96d56Sopenharmony_ci Coordinate.PY 8827db96d56Sopenharmony_ci 8837db96d56Sopenharmony_ci >>> print(Coordinate(3)) 8847db96d56Sopenharmony_ci Coordinate.VY 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci 8877db96d56Sopenharmony_ciFiner Points 8887db96d56Sopenharmony_ci^^^^^^^^^^^^ 8897db96d56Sopenharmony_ci 8907db96d56Sopenharmony_ciSupported ``__dunder__`` names 8917db96d56Sopenharmony_ci"""""""""""""""""""""""""""""" 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci:attr:`__members__` is a read-only ordered mapping of ``member_name``:``member`` 8947db96d56Sopenharmony_ciitems. It is only available on the class. 8957db96d56Sopenharmony_ci 8967db96d56Sopenharmony_ci:meth:`__new__`, if specified, must create and return the enum members; it is 8977db96d56Sopenharmony_cialso a very good idea to set the member's :attr:`_value_` appropriately. Once 8987db96d56Sopenharmony_ciall the members are created it is no longer used. 8997db96d56Sopenharmony_ci 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_ciSupported ``_sunder_`` names 9027db96d56Sopenharmony_ci"""""""""""""""""""""""""""" 9037db96d56Sopenharmony_ci 9047db96d56Sopenharmony_ci- ``_name_`` -- name of the member 9057db96d56Sopenharmony_ci- ``_value_`` -- value of the member; can be set / modified in ``__new__`` 9067db96d56Sopenharmony_ci 9077db96d56Sopenharmony_ci- ``_missing_`` -- a lookup function used when a value is not found; may be 9087db96d56Sopenharmony_ci overridden 9097db96d56Sopenharmony_ci- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`, 9107db96d56Sopenharmony_ci that will not be transformed into members, and will be removed from the final 9117db96d56Sopenharmony_ci class 9127db96d56Sopenharmony_ci- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent 9137db96d56Sopenharmony_ci (class attribute, removed during class creation) 9147db96d56Sopenharmony_ci- ``_generate_next_value_`` -- used by the `Functional API`_ and by 9157db96d56Sopenharmony_ci :class:`auto` to get an appropriate value for an enum member; may be 9167db96d56Sopenharmony_ci overridden 9177db96d56Sopenharmony_ci 9187db96d56Sopenharmony_ci.. note:: 9197db96d56Sopenharmony_ci 9207db96d56Sopenharmony_ci For standard :class:`Enum` classes the next value chosen is the last value seen 9217db96d56Sopenharmony_ci incremented by one. 9227db96d56Sopenharmony_ci 9237db96d56Sopenharmony_ci For :class:`Flag` classes the next value chosen will be the next highest 9247db96d56Sopenharmony_ci power-of-two, regardless of the last value seen. 9257db96d56Sopenharmony_ci 9267db96d56Sopenharmony_ci.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` 9277db96d56Sopenharmony_ci.. versionadded:: 3.7 ``_ignore_`` 9287db96d56Sopenharmony_ci 9297db96d56Sopenharmony_ciTo help keep Python 2 / Python 3 code in sync an :attr:`_order_` attribute can 9307db96d56Sopenharmony_cibe provided. It will be checked against the actual order of the enumeration 9317db96d56Sopenharmony_ciand raise an error if the two do not match:: 9327db96d56Sopenharmony_ci 9337db96d56Sopenharmony_ci >>> class Color(Enum): 9347db96d56Sopenharmony_ci ... _order_ = 'RED GREEN BLUE' 9357db96d56Sopenharmony_ci ... RED = 1 9367db96d56Sopenharmony_ci ... BLUE = 3 9377db96d56Sopenharmony_ci ... GREEN = 2 9387db96d56Sopenharmony_ci ... 9397db96d56Sopenharmony_ci Traceback (most recent call last): 9407db96d56Sopenharmony_ci ... 9417db96d56Sopenharmony_ci TypeError: member order does not match _order_: 9427db96d56Sopenharmony_ci ['RED', 'BLUE', 'GREEN'] 9437db96d56Sopenharmony_ci ['RED', 'GREEN', 'BLUE'] 9447db96d56Sopenharmony_ci 9457db96d56Sopenharmony_ci.. note:: 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_ci In Python 2 code the :attr:`_order_` attribute is necessary as definition 9487db96d56Sopenharmony_ci order is lost before it can be recorded. 9497db96d56Sopenharmony_ci 9507db96d56Sopenharmony_ci 9517db96d56Sopenharmony_ci_Private__names 9527db96d56Sopenharmony_ci""""""""""""""" 9537db96d56Sopenharmony_ci 9547db96d56Sopenharmony_ci:ref:`Private names <private-name-mangling>` are not converted to enum members, 9557db96d56Sopenharmony_cibut remain normal attributes. 9567db96d56Sopenharmony_ci 9577db96d56Sopenharmony_ci.. versionchanged:: 3.11 9587db96d56Sopenharmony_ci 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_ci``Enum`` member type 9617db96d56Sopenharmony_ci"""""""""""""""""""" 9627db96d56Sopenharmony_ci 9637db96d56Sopenharmony_ciEnum members are instances of their enum class, and are normally accessed as 9647db96d56Sopenharmony_ci``EnumClass.member``. In certain situations, such as writing custom enum 9657db96d56Sopenharmony_cibehavior, being able to access one member directly from another is useful, 9667db96d56Sopenharmony_ciand is supported. 9677db96d56Sopenharmony_ci 9687db96d56Sopenharmony_ci.. versionchanged:: 3.5 9697db96d56Sopenharmony_ci 9707db96d56Sopenharmony_ci 9717db96d56Sopenharmony_ciCreating members that are mixed with other data types 9727db96d56Sopenharmony_ci""""""""""""""""""""""""""""""""""""""""""""""""""""" 9737db96d56Sopenharmony_ci 9747db96d56Sopenharmony_ciWhen subclassing other data types, such as :class:`int` or :class:`str`, with 9757db96d56Sopenharmony_cian :class:`Enum`, all values after the ``=`` are passed to that data type's 9767db96d56Sopenharmony_ciconstructor. For example:: 9777db96d56Sopenharmony_ci 9787db96d56Sopenharmony_ci >>> class MyEnum(IntEnum): # help(int) -> int(x, base=10) -> integer 9797db96d56Sopenharmony_ci ... example = '11', 16 # so x='11' and base=16 9807db96d56Sopenharmony_ci ... 9817db96d56Sopenharmony_ci >>> MyEnum.example.value # and hex(11) is... 9827db96d56Sopenharmony_ci 17 9837db96d56Sopenharmony_ci 9847db96d56Sopenharmony_ci 9857db96d56Sopenharmony_ciBoolean value of ``Enum`` classes and members 9867db96d56Sopenharmony_ci""""""""""""""""""""""""""""""""""""""""""""" 9877db96d56Sopenharmony_ci 9887db96d56Sopenharmony_ciEnum classes that are mixed with non-:class:`Enum` types (such as 9897db96d56Sopenharmony_ci:class:`int`, :class:`str`, etc.) are evaluated according to the mixed-in 9907db96d56Sopenharmony_citype's rules; otherwise, all members evaluate as :data:`True`. To make your 9917db96d56Sopenharmony_ciown enum's boolean evaluation depend on the member's value add the following to 9927db96d56Sopenharmony_ciyour class:: 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_ci def __bool__(self): 9957db96d56Sopenharmony_ci return bool(self.value) 9967db96d56Sopenharmony_ci 9977db96d56Sopenharmony_ciPlain :class:`Enum` classes always evaluate as :data:`True`. 9987db96d56Sopenharmony_ci 9997db96d56Sopenharmony_ci 10007db96d56Sopenharmony_ci``Enum`` classes with methods 10017db96d56Sopenharmony_ci""""""""""""""""""""""""""""" 10027db96d56Sopenharmony_ci 10037db96d56Sopenharmony_ciIf you give your enum subclass extra methods, like the `Planet`_ 10047db96d56Sopenharmony_ciclass below, those methods will show up in a :func:`dir` of the member, 10057db96d56Sopenharmony_cibut not of the class:: 10067db96d56Sopenharmony_ci 10077db96d56Sopenharmony_ci >>> dir(Planet) # doctest: +SKIP 10087db96d56Sopenharmony_ci ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__'] 10097db96d56Sopenharmony_ci >>> dir(Planet.EARTH) # doctest: +SKIP 10107db96d56Sopenharmony_ci ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value'] 10117db96d56Sopenharmony_ci 10127db96d56Sopenharmony_ci 10137db96d56Sopenharmony_ciCombining members of ``Flag`` 10147db96d56Sopenharmony_ci""""""""""""""""""""""""""""" 10157db96d56Sopenharmony_ci 10167db96d56Sopenharmony_ciIterating over a combination of :class:`Flag` members will only return the members that 10177db96d56Sopenharmony_ciare comprised of a single bit:: 10187db96d56Sopenharmony_ci 10197db96d56Sopenharmony_ci >>> class Color(Flag): 10207db96d56Sopenharmony_ci ... RED = auto() 10217db96d56Sopenharmony_ci ... GREEN = auto() 10227db96d56Sopenharmony_ci ... BLUE = auto() 10237db96d56Sopenharmony_ci ... MAGENTA = RED | BLUE 10247db96d56Sopenharmony_ci ... YELLOW = RED | GREEN 10257db96d56Sopenharmony_ci ... CYAN = GREEN | BLUE 10267db96d56Sopenharmony_ci ... 10277db96d56Sopenharmony_ci >>> Color(3) # named combination 10287db96d56Sopenharmony_ci <Color.YELLOW: 3> 10297db96d56Sopenharmony_ci >>> Color(7) # not named combination 10307db96d56Sopenharmony_ci <Color.RED|GREEN|BLUE: 7> 10317db96d56Sopenharmony_ci 10327db96d56Sopenharmony_ci 10337db96d56Sopenharmony_ci``Flag`` and ``IntFlag`` minutia 10347db96d56Sopenharmony_ci"""""""""""""""""""""""""""""""" 10357db96d56Sopenharmony_ci 10367db96d56Sopenharmony_ciUsing the following snippet for our examples:: 10377db96d56Sopenharmony_ci 10387db96d56Sopenharmony_ci >>> class Color(IntFlag): 10397db96d56Sopenharmony_ci ... BLACK = 0 10407db96d56Sopenharmony_ci ... RED = 1 10417db96d56Sopenharmony_ci ... GREEN = 2 10427db96d56Sopenharmony_ci ... BLUE = 4 10437db96d56Sopenharmony_ci ... PURPLE = RED | BLUE 10447db96d56Sopenharmony_ci ... WHITE = RED | GREEN | BLUE 10457db96d56Sopenharmony_ci ... 10467db96d56Sopenharmony_ci 10477db96d56Sopenharmony_cithe following are true: 10487db96d56Sopenharmony_ci 10497db96d56Sopenharmony_ci- single-bit flags are canonical 10507db96d56Sopenharmony_ci- multi-bit and zero-bit flags are aliases 10517db96d56Sopenharmony_ci- only canonical flags are returned during iteration:: 10527db96d56Sopenharmony_ci 10537db96d56Sopenharmony_ci >>> list(Color.WHITE) 10547db96d56Sopenharmony_ci [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>] 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_ci- negating a flag or flag set returns a new flag/flag set with the 10577db96d56Sopenharmony_ci corresponding positive integer value:: 10587db96d56Sopenharmony_ci 10597db96d56Sopenharmony_ci >>> Color.BLUE 10607db96d56Sopenharmony_ci <Color.BLUE: 4> 10617db96d56Sopenharmony_ci 10627db96d56Sopenharmony_ci >>> ~Color.BLUE 10637db96d56Sopenharmony_ci <Color.RED|GREEN: 3> 10647db96d56Sopenharmony_ci 10657db96d56Sopenharmony_ci- names of pseudo-flags are constructed from their members' names:: 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci >>> (Color.RED | Color.GREEN).name 10687db96d56Sopenharmony_ci 'RED|GREEN' 10697db96d56Sopenharmony_ci 10707db96d56Sopenharmony_ci- multi-bit flags, aka aliases, can be returned from operations:: 10717db96d56Sopenharmony_ci 10727db96d56Sopenharmony_ci >>> Color.RED | Color.BLUE 10737db96d56Sopenharmony_ci <Color.PURPLE: 5> 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ci >>> Color(7) # or Color(-1) 10767db96d56Sopenharmony_ci <Color.WHITE: 7> 10777db96d56Sopenharmony_ci 10787db96d56Sopenharmony_ci >>> Color(0) 10797db96d56Sopenharmony_ci <Color.BLACK: 0> 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_ci- membership / containment checking: zero-valued flags are always considered 10827db96d56Sopenharmony_ci to be contained:: 10837db96d56Sopenharmony_ci 10847db96d56Sopenharmony_ci >>> Color.BLACK in Color.WHITE 10857db96d56Sopenharmony_ci True 10867db96d56Sopenharmony_ci 10877db96d56Sopenharmony_ci otherwise, only if all bits of one flag are in the other flag will True 10887db96d56Sopenharmony_ci be returned:: 10897db96d56Sopenharmony_ci 10907db96d56Sopenharmony_ci >>> Color.PURPLE in Color.WHITE 10917db96d56Sopenharmony_ci True 10927db96d56Sopenharmony_ci 10937db96d56Sopenharmony_ci >>> Color.GREEN in Color.PURPLE 10947db96d56Sopenharmony_ci False 10957db96d56Sopenharmony_ci 10967db96d56Sopenharmony_ciThere is a new boundary mechanism that controls how out-of-range / invalid 10977db96d56Sopenharmony_cibits are handled: ``STRICT``, ``CONFORM``, ``EJECT``, and ``KEEP``: 10987db96d56Sopenharmony_ci 10997db96d56Sopenharmony_ci * STRICT --> raises an exception when presented with invalid values 11007db96d56Sopenharmony_ci * CONFORM --> discards any invalid bits 11017db96d56Sopenharmony_ci * EJECT --> lose Flag status and become a normal int with the given value 11027db96d56Sopenharmony_ci * KEEP --> keep the extra bits 11037db96d56Sopenharmony_ci - keeps Flag status and extra bits 11047db96d56Sopenharmony_ci - extra bits do not show up in iteration 11057db96d56Sopenharmony_ci - extra bits do show up in repr() and str() 11067db96d56Sopenharmony_ci 11077db96d56Sopenharmony_ciThe default for Flag is ``STRICT``, the default for ``IntFlag`` is ``EJECT``, 11087db96d56Sopenharmony_ciand the default for ``_convert_`` is ``KEEP`` (see ``ssl.Options`` for an 11097db96d56Sopenharmony_ciexample of when ``KEEP`` is needed). 11107db96d56Sopenharmony_ci 11117db96d56Sopenharmony_ci 11127db96d56Sopenharmony_ci.. _enum-class-differences: 11137db96d56Sopenharmony_ci 11147db96d56Sopenharmony_ciHow are Enums and Flags different? 11157db96d56Sopenharmony_ci---------------------------------- 11167db96d56Sopenharmony_ci 11177db96d56Sopenharmony_ciEnums have a custom metaclass that affects many aspects of both derived :class:`Enum` 11187db96d56Sopenharmony_ciclasses and their instances (members). 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ci 11217db96d56Sopenharmony_ciEnum Classes 11227db96d56Sopenharmony_ci^^^^^^^^^^^^ 11237db96d56Sopenharmony_ci 11247db96d56Sopenharmony_ciThe :class:`EnumType` metaclass is responsible for providing the 11257db96d56Sopenharmony_ci:meth:`__contains__`, :meth:`__dir__`, :meth:`__iter__` and other methods that 11267db96d56Sopenharmony_ciallow one to do things with an :class:`Enum` class that fail on a typical 11277db96d56Sopenharmony_ciclass, such as ``list(Color)`` or ``some_enum_var in Color``. :class:`EnumType` is 11287db96d56Sopenharmony_ciresponsible for ensuring that various other methods on the final :class:`Enum` 11297db96d56Sopenharmony_ciclass are correct (such as :meth:`__new__`, :meth:`__getnewargs__`, 11307db96d56Sopenharmony_ci:meth:`__str__` and :meth:`__repr__`). 11317db96d56Sopenharmony_ci 11327db96d56Sopenharmony_ciFlag Classes 11337db96d56Sopenharmony_ci^^^^^^^^^^^^ 11347db96d56Sopenharmony_ci 11357db96d56Sopenharmony_ciFlags have an expanded view of aliasing: to be canonical, the value of a flag 11367db96d56Sopenharmony_cineeds to be a power-of-two value, and not a duplicate name. So, in addition to the 11377db96d56Sopenharmony_ci:class:`Enum` definition of alias, a flag with no value (a.k.a. ``0``) or with more than one 11387db96d56Sopenharmony_cipower-of-two value (e.g. ``3``) is considered an alias. 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_ciEnum Members (aka instances) 11417db96d56Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 11427db96d56Sopenharmony_ci 11437db96d56Sopenharmony_ciThe most interesting thing about enum members is that they are singletons. 11447db96d56Sopenharmony_ci:class:`EnumType` creates them all while it is creating the enum class itself, 11457db96d56Sopenharmony_ciand then puts a custom :meth:`__new__` in place to ensure that no new ones are 11467db96d56Sopenharmony_ciever instantiated by returning only the existing member instances. 11477db96d56Sopenharmony_ci 11487db96d56Sopenharmony_ciFlag Members 11497db96d56Sopenharmony_ci^^^^^^^^^^^^ 11507db96d56Sopenharmony_ci 11517db96d56Sopenharmony_ciFlag members can be iterated over just like the :class:`Flag` class, and only the 11527db96d56Sopenharmony_cicanonical members will be returned. For example:: 11537db96d56Sopenharmony_ci 11547db96d56Sopenharmony_ci >>> list(Color) 11557db96d56Sopenharmony_ci [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>] 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ci(Note that ``BLACK``, ``PURPLE``, and ``WHITE`` do not show up.) 11587db96d56Sopenharmony_ci 11597db96d56Sopenharmony_ciInverting a flag member returns the corresponding positive value, 11607db96d56Sopenharmony_cirather than a negative value --- for example:: 11617db96d56Sopenharmony_ci 11627db96d56Sopenharmony_ci >>> ~Color.RED 11637db96d56Sopenharmony_ci <Color.GREEN|BLUE: 6> 11647db96d56Sopenharmony_ci 11657db96d56Sopenharmony_ciFlag members have a length corresponding to the number of power-of-two values 11667db96d56Sopenharmony_cithey contain. For example:: 11677db96d56Sopenharmony_ci 11687db96d56Sopenharmony_ci >>> len(Color.PURPLE) 11697db96d56Sopenharmony_ci 2 11707db96d56Sopenharmony_ci 11717db96d56Sopenharmony_ci 11727db96d56Sopenharmony_ci.. _enum-cookbook: 11737db96d56Sopenharmony_ci 11747db96d56Sopenharmony_ciEnum Cookbook 11757db96d56Sopenharmony_ci------------- 11767db96d56Sopenharmony_ci 11777db96d56Sopenharmony_ci 11787db96d56Sopenharmony_ciWhile :class:`Enum`, :class:`IntEnum`, :class:`StrEnum`, :class:`Flag`, and 11797db96d56Sopenharmony_ci:class:`IntFlag` are expected to cover the majority of use-cases, they cannot 11807db96d56Sopenharmony_cicover them all. Here are recipes for some different types of enumerations 11817db96d56Sopenharmony_cithat can be used directly, or as examples for creating one's own. 11827db96d56Sopenharmony_ci 11837db96d56Sopenharmony_ci 11847db96d56Sopenharmony_ciOmitting values 11857db96d56Sopenharmony_ci^^^^^^^^^^^^^^^ 11867db96d56Sopenharmony_ci 11877db96d56Sopenharmony_ciIn many use-cases, one doesn't care what the actual value of an enumeration 11887db96d56Sopenharmony_ciis. There are several ways to define this type of simple enumeration: 11897db96d56Sopenharmony_ci 11907db96d56Sopenharmony_ci- use instances of :class:`auto` for the value 11917db96d56Sopenharmony_ci- use instances of :class:`object` as the value 11927db96d56Sopenharmony_ci- use a descriptive string as the value 11937db96d56Sopenharmony_ci- use a tuple as the value and a custom :meth:`__new__` to replace the 11947db96d56Sopenharmony_ci tuple with an :class:`int` value 11957db96d56Sopenharmony_ci 11967db96d56Sopenharmony_ciUsing any of these methods signifies to the user that these values are not 11977db96d56Sopenharmony_ciimportant, and also enables one to add, remove, or reorder members without 11987db96d56Sopenharmony_cihaving to renumber the remaining members. 11997db96d56Sopenharmony_ci 12007db96d56Sopenharmony_ci 12017db96d56Sopenharmony_ciUsing :class:`auto` 12027db96d56Sopenharmony_ci""""""""""""""""""" 12037db96d56Sopenharmony_ci 12047db96d56Sopenharmony_ciUsing :class:`auto` would look like:: 12057db96d56Sopenharmony_ci 12067db96d56Sopenharmony_ci >>> class Color(Enum): 12077db96d56Sopenharmony_ci ... RED = auto() 12087db96d56Sopenharmony_ci ... BLUE = auto() 12097db96d56Sopenharmony_ci ... GREEN = auto() 12107db96d56Sopenharmony_ci ... 12117db96d56Sopenharmony_ci >>> Color.GREEN 12127db96d56Sopenharmony_ci <Color.GREEN: 3> 12137db96d56Sopenharmony_ci 12147db96d56Sopenharmony_ci 12157db96d56Sopenharmony_ciUsing :class:`object` 12167db96d56Sopenharmony_ci""""""""""""""""""""" 12177db96d56Sopenharmony_ci 12187db96d56Sopenharmony_ciUsing :class:`object` would look like:: 12197db96d56Sopenharmony_ci 12207db96d56Sopenharmony_ci >>> class Color(Enum): 12217db96d56Sopenharmony_ci ... RED = object() 12227db96d56Sopenharmony_ci ... GREEN = object() 12237db96d56Sopenharmony_ci ... BLUE = object() 12247db96d56Sopenharmony_ci ... 12257db96d56Sopenharmony_ci >>> Color.GREEN # doctest: +SKIP 12267db96d56Sopenharmony_ci <Color.GREEN: <object object at 0x...>> 12277db96d56Sopenharmony_ci 12287db96d56Sopenharmony_ciThis is also a good example of why you might want to write your own 12297db96d56Sopenharmony_ci:meth:`__repr__`:: 12307db96d56Sopenharmony_ci 12317db96d56Sopenharmony_ci >>> class Color(Enum): 12327db96d56Sopenharmony_ci ... RED = object() 12337db96d56Sopenharmony_ci ... GREEN = object() 12347db96d56Sopenharmony_ci ... BLUE = object() 12357db96d56Sopenharmony_ci ... def __repr__(self): 12367db96d56Sopenharmony_ci ... return "<%s.%s>" % (self.__class__.__name__, self._name_) 12377db96d56Sopenharmony_ci ... 12387db96d56Sopenharmony_ci >>> Color.GREEN 12397db96d56Sopenharmony_ci <Color.GREEN> 12407db96d56Sopenharmony_ci 12417db96d56Sopenharmony_ci 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ciUsing a descriptive string 12447db96d56Sopenharmony_ci"""""""""""""""""""""""""" 12457db96d56Sopenharmony_ci 12467db96d56Sopenharmony_ciUsing a string as the value would look like:: 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci >>> class Color(Enum): 12497db96d56Sopenharmony_ci ... RED = 'stop' 12507db96d56Sopenharmony_ci ... GREEN = 'go' 12517db96d56Sopenharmony_ci ... BLUE = 'too fast!' 12527db96d56Sopenharmony_ci ... 12537db96d56Sopenharmony_ci >>> Color.GREEN 12547db96d56Sopenharmony_ci <Color.GREEN: 'go'> 12557db96d56Sopenharmony_ci 12567db96d56Sopenharmony_ci 12577db96d56Sopenharmony_ciUsing a custom :meth:`__new__` 12587db96d56Sopenharmony_ci"""""""""""""""""""""""""""""" 12597db96d56Sopenharmony_ci 12607db96d56Sopenharmony_ciUsing an auto-numbering :meth:`__new__` would look like:: 12617db96d56Sopenharmony_ci 12627db96d56Sopenharmony_ci >>> class AutoNumber(Enum): 12637db96d56Sopenharmony_ci ... def __new__(cls): 12647db96d56Sopenharmony_ci ... value = len(cls.__members__) + 1 12657db96d56Sopenharmony_ci ... obj = object.__new__(cls) 12667db96d56Sopenharmony_ci ... obj._value_ = value 12677db96d56Sopenharmony_ci ... return obj 12687db96d56Sopenharmony_ci ... 12697db96d56Sopenharmony_ci >>> class Color(AutoNumber): 12707db96d56Sopenharmony_ci ... RED = () 12717db96d56Sopenharmony_ci ... GREEN = () 12727db96d56Sopenharmony_ci ... BLUE = () 12737db96d56Sopenharmony_ci ... 12747db96d56Sopenharmony_ci >>> Color.GREEN 12757db96d56Sopenharmony_ci <Color.GREEN: 2> 12767db96d56Sopenharmony_ci 12777db96d56Sopenharmony_ciTo make a more general purpose ``AutoNumber``, add ``*args`` to the signature:: 12787db96d56Sopenharmony_ci 12797db96d56Sopenharmony_ci >>> class AutoNumber(Enum): 12807db96d56Sopenharmony_ci ... def __new__(cls, *args): # this is the only change from above 12817db96d56Sopenharmony_ci ... value = len(cls.__members__) + 1 12827db96d56Sopenharmony_ci ... obj = object.__new__(cls) 12837db96d56Sopenharmony_ci ... obj._value_ = value 12847db96d56Sopenharmony_ci ... return obj 12857db96d56Sopenharmony_ci ... 12867db96d56Sopenharmony_ci 12877db96d56Sopenharmony_ciThen when you inherit from ``AutoNumber`` you can write your own ``__init__`` 12887db96d56Sopenharmony_cito handle any extra arguments:: 12897db96d56Sopenharmony_ci 12907db96d56Sopenharmony_ci >>> class Swatch(AutoNumber): 12917db96d56Sopenharmony_ci ... def __init__(self, pantone='unknown'): 12927db96d56Sopenharmony_ci ... self.pantone = pantone 12937db96d56Sopenharmony_ci ... AUBURN = '3497' 12947db96d56Sopenharmony_ci ... SEA_GREEN = '1246' 12957db96d56Sopenharmony_ci ... BLEACHED_CORAL = () # New color, no Pantone code yet! 12967db96d56Sopenharmony_ci ... 12977db96d56Sopenharmony_ci >>> Swatch.SEA_GREEN 12987db96d56Sopenharmony_ci <Swatch.SEA_GREEN: 2> 12997db96d56Sopenharmony_ci >>> Swatch.SEA_GREEN.pantone 13007db96d56Sopenharmony_ci '1246' 13017db96d56Sopenharmony_ci >>> Swatch.BLEACHED_CORAL.pantone 13027db96d56Sopenharmony_ci 'unknown' 13037db96d56Sopenharmony_ci 13047db96d56Sopenharmony_ci.. note:: 13057db96d56Sopenharmony_ci 13067db96d56Sopenharmony_ci The :meth:`__new__` method, if defined, is used during creation of the Enum 13077db96d56Sopenharmony_ci members; it is then replaced by Enum's :meth:`__new__` which is used after 13087db96d56Sopenharmony_ci class creation for lookup of existing members. 13097db96d56Sopenharmony_ci 13107db96d56Sopenharmony_ci 13117db96d56Sopenharmony_ciOrderedEnum 13127db96d56Sopenharmony_ci^^^^^^^^^^^ 13137db96d56Sopenharmony_ci 13147db96d56Sopenharmony_ciAn ordered enumeration that is not based on :class:`IntEnum` and so maintains 13157db96d56Sopenharmony_cithe normal :class:`Enum` invariants (such as not being comparable to other 13167db96d56Sopenharmony_cienumerations):: 13177db96d56Sopenharmony_ci 13187db96d56Sopenharmony_ci >>> class OrderedEnum(Enum): 13197db96d56Sopenharmony_ci ... def __ge__(self, other): 13207db96d56Sopenharmony_ci ... if self.__class__ is other.__class__: 13217db96d56Sopenharmony_ci ... return self.value >= other.value 13227db96d56Sopenharmony_ci ... return NotImplemented 13237db96d56Sopenharmony_ci ... def __gt__(self, other): 13247db96d56Sopenharmony_ci ... if self.__class__ is other.__class__: 13257db96d56Sopenharmony_ci ... return self.value > other.value 13267db96d56Sopenharmony_ci ... return NotImplemented 13277db96d56Sopenharmony_ci ... def __le__(self, other): 13287db96d56Sopenharmony_ci ... if self.__class__ is other.__class__: 13297db96d56Sopenharmony_ci ... return self.value <= other.value 13307db96d56Sopenharmony_ci ... return NotImplemented 13317db96d56Sopenharmony_ci ... def __lt__(self, other): 13327db96d56Sopenharmony_ci ... if self.__class__ is other.__class__: 13337db96d56Sopenharmony_ci ... return self.value < other.value 13347db96d56Sopenharmony_ci ... return NotImplemented 13357db96d56Sopenharmony_ci ... 13367db96d56Sopenharmony_ci >>> class Grade(OrderedEnum): 13377db96d56Sopenharmony_ci ... A = 5 13387db96d56Sopenharmony_ci ... B = 4 13397db96d56Sopenharmony_ci ... C = 3 13407db96d56Sopenharmony_ci ... D = 2 13417db96d56Sopenharmony_ci ... F = 1 13427db96d56Sopenharmony_ci ... 13437db96d56Sopenharmony_ci >>> Grade.C < Grade.A 13447db96d56Sopenharmony_ci True 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ci 13477db96d56Sopenharmony_ciDuplicateFreeEnum 13487db96d56Sopenharmony_ci^^^^^^^^^^^^^^^^^ 13497db96d56Sopenharmony_ci 13507db96d56Sopenharmony_ciRaises an error if a duplicate member value is found instead of creating an 13517db96d56Sopenharmony_cialias:: 13527db96d56Sopenharmony_ci 13537db96d56Sopenharmony_ci >>> class DuplicateFreeEnum(Enum): 13547db96d56Sopenharmony_ci ... def __init__(self, *args): 13557db96d56Sopenharmony_ci ... cls = self.__class__ 13567db96d56Sopenharmony_ci ... if any(self.value == e.value for e in cls): 13577db96d56Sopenharmony_ci ... a = self.name 13587db96d56Sopenharmony_ci ... e = cls(self.value).name 13597db96d56Sopenharmony_ci ... raise ValueError( 13607db96d56Sopenharmony_ci ... "aliases not allowed in DuplicateFreeEnum: %r --> %r" 13617db96d56Sopenharmony_ci ... % (a, e)) 13627db96d56Sopenharmony_ci ... 13637db96d56Sopenharmony_ci >>> class Color(DuplicateFreeEnum): 13647db96d56Sopenharmony_ci ... RED = 1 13657db96d56Sopenharmony_ci ... GREEN = 2 13667db96d56Sopenharmony_ci ... BLUE = 3 13677db96d56Sopenharmony_ci ... GRENE = 2 13687db96d56Sopenharmony_ci ... 13697db96d56Sopenharmony_ci Traceback (most recent call last): 13707db96d56Sopenharmony_ci ... 13717db96d56Sopenharmony_ci ValueError: aliases not allowed in DuplicateFreeEnum: 'GRENE' --> 'GREEN' 13727db96d56Sopenharmony_ci 13737db96d56Sopenharmony_ci.. note:: 13747db96d56Sopenharmony_ci 13757db96d56Sopenharmony_ci This is a useful example for subclassing Enum to add or change other 13767db96d56Sopenharmony_ci behaviors as well as disallowing aliases. If the only desired change is 13777db96d56Sopenharmony_ci disallowing aliases, the :func:`unique` decorator can be used instead. 13787db96d56Sopenharmony_ci 13797db96d56Sopenharmony_ci 13807db96d56Sopenharmony_ciPlanet 13817db96d56Sopenharmony_ci^^^^^^ 13827db96d56Sopenharmony_ci 13837db96d56Sopenharmony_ciIf :meth:`__new__` or :meth:`__init__` is defined, the value of the enum member 13847db96d56Sopenharmony_ciwill be passed to those methods:: 13857db96d56Sopenharmony_ci 13867db96d56Sopenharmony_ci >>> class Planet(Enum): 13877db96d56Sopenharmony_ci ... MERCURY = (3.303e+23, 2.4397e6) 13887db96d56Sopenharmony_ci ... VENUS = (4.869e+24, 6.0518e6) 13897db96d56Sopenharmony_ci ... EARTH = (5.976e+24, 6.37814e6) 13907db96d56Sopenharmony_ci ... MARS = (6.421e+23, 3.3972e6) 13917db96d56Sopenharmony_ci ... JUPITER = (1.9e+27, 7.1492e7) 13927db96d56Sopenharmony_ci ... SATURN = (5.688e+26, 6.0268e7) 13937db96d56Sopenharmony_ci ... URANUS = (8.686e+25, 2.5559e7) 13947db96d56Sopenharmony_ci ... NEPTUNE = (1.024e+26, 2.4746e7) 13957db96d56Sopenharmony_ci ... def __init__(self, mass, radius): 13967db96d56Sopenharmony_ci ... self.mass = mass # in kilograms 13977db96d56Sopenharmony_ci ... self.radius = radius # in meters 13987db96d56Sopenharmony_ci ... @property 13997db96d56Sopenharmony_ci ... def surface_gravity(self): 14007db96d56Sopenharmony_ci ... # universal gravitational constant (m3 kg-1 s-2) 14017db96d56Sopenharmony_ci ... G = 6.67300E-11 14027db96d56Sopenharmony_ci ... return G * self.mass / (self.radius * self.radius) 14037db96d56Sopenharmony_ci ... 14047db96d56Sopenharmony_ci >>> Planet.EARTH.value 14057db96d56Sopenharmony_ci (5.976e+24, 6378140.0) 14067db96d56Sopenharmony_ci >>> Planet.EARTH.surface_gravity 14077db96d56Sopenharmony_ci 9.802652743337129 14087db96d56Sopenharmony_ci 14097db96d56Sopenharmony_ci.. _enum-time-period: 14107db96d56Sopenharmony_ci 14117db96d56Sopenharmony_ciTimePeriod 14127db96d56Sopenharmony_ci^^^^^^^^^^ 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ciAn example to show the :attr:`_ignore_` attribute in use:: 14157db96d56Sopenharmony_ci 14167db96d56Sopenharmony_ci >>> from datetime import timedelta 14177db96d56Sopenharmony_ci >>> class Period(timedelta, Enum): 14187db96d56Sopenharmony_ci ... "different lengths of time" 14197db96d56Sopenharmony_ci ... _ignore_ = 'Period i' 14207db96d56Sopenharmony_ci ... Period = vars() 14217db96d56Sopenharmony_ci ... for i in range(367): 14227db96d56Sopenharmony_ci ... Period['day_%d' % i] = i 14237db96d56Sopenharmony_ci ... 14247db96d56Sopenharmony_ci >>> list(Period)[:2] 14257db96d56Sopenharmony_ci [<Period.day_0: datetime.timedelta(0)>, <Period.day_1: datetime.timedelta(days=1)>] 14267db96d56Sopenharmony_ci >>> list(Period)[-2:] 14277db96d56Sopenharmony_ci [<Period.day_365: datetime.timedelta(days=365)>, <Period.day_366: datetime.timedelta(days=366)>] 14287db96d56Sopenharmony_ci 14297db96d56Sopenharmony_ci 14307db96d56Sopenharmony_ci.. _enumtype-examples: 14317db96d56Sopenharmony_ci 14327db96d56Sopenharmony_ciSubclassing EnumType 14337db96d56Sopenharmony_ci-------------------- 14347db96d56Sopenharmony_ci 14357db96d56Sopenharmony_ciWhile most enum needs can be met by customizing :class:`Enum` subclasses, 14367db96d56Sopenharmony_cieither with class decorators or custom functions, :class:`EnumType` can be 14377db96d56Sopenharmony_cisubclassed to provide a different Enum experience. 1438