Updates based on recent enhancements in flufl.enum + some clarifications.
More TODOs remain: importantly, the improved convenience/functional API.
This commit is contained in:
parent
e3654917be
commit
cb3c841bab
85
pep-0435.txt
85
pep-0435.txt
|
@ -27,6 +27,12 @@ and from their integer equivalents, supporting use cases such as storing
|
|||
enumeration values in a database.
|
||||
|
||||
|
||||
Decision
|
||||
========
|
||||
|
||||
TODO: update decision here once pronouncement is made.
|
||||
|
||||
|
||||
Status of discussions
|
||||
=====================
|
||||
|
||||
|
@ -263,39 +269,9 @@ that expect integers::
|
|||
>>> int(Colors.blue)
|
||||
3
|
||||
|
||||
You can also convert back to the enumeration value by calling the Enum
|
||||
You can also convert back to the enumeration value by indexing into the Enum
|
||||
subclass, passing in the integer value for the item you want::
|
||||
|
||||
>>> Colors(1)
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
>>> Colors(2)
|
||||
<EnumValue: Colors.green [int=2]>
|
||||
>>> Colors(3)
|
||||
<EnumValue: Colors.blue [int=3]>
|
||||
>>> Colors(1) is Colors.red
|
||||
True
|
||||
|
||||
The Enum subclass also accepts the string name of the enumeration value::
|
||||
|
||||
>>> Colors('red')
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
>>> Colors('blue') is Colors.blue
|
||||
True
|
||||
|
||||
You get exceptions though, if you try to use invalid arguments::
|
||||
|
||||
>>> Colors('magenta')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: magenta
|
||||
>>> Colors(99)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: 99
|
||||
|
||||
The Enum base class also supports getitem syntax, exactly equivalent to the
|
||||
class's call semantics::
|
||||
|
||||
>>> Colors[1]
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
>>> Colors[2]
|
||||
|
@ -304,10 +280,16 @@ class's call semantics::
|
|||
<EnumValue: Colors.blue [int=3]>
|
||||
>>> Colors[1] is Colors.red
|
||||
True
|
||||
|
||||
The string name of the enumeration value is also accepted::
|
||||
|
||||
>>> Colors['red']
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
>>> Colors['blue'] is Colors.blue
|
||||
True
|
||||
|
||||
You get exceptions though, if you try to use invalid arguments::
|
||||
|
||||
>>> Colors['magenta']
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -357,7 +339,6 @@ Enumeration values are hashable, so they can be used in dictionaries and sets::
|
|||
red -> red delicious
|
||||
green -> granny smith
|
||||
|
||||
|
||||
IntEnum
|
||||
-------
|
||||
|
||||
|
@ -396,9 +377,12 @@ However they still can't be compared to ``Enum``::
|
|||
>>> Shape.circle == Colors.red
|
||||
False
|
||||
|
||||
For the vast majority of code, ``Enum`` is recommended. Only if a greater
|
||||
degree of interoperatility with integers is required and ``Enum`` does not
|
||||
fit the bill, ``IntEnum`` should be used.
|
||||
For the vast majority of code, ``Enum`` is strongly recommended. Since
|
||||
``IntEnum`` breaks some semantic promises of an enumeration (by being comparable
|
||||
to integers, and thus by transitivity to other unrelated enumerations), it
|
||||
should be used only in special cases where there's no other choice; for example,
|
||||
when integer constants are replaced with enumerations and backwards
|
||||
compatibility is required with code that still expects integers.
|
||||
|
||||
Pickling
|
||||
--------
|
||||
|
@ -410,10 +394,11 @@ Enumerations created with the class syntax can also be pickled and unpickled::
|
|||
>>> Fruit.tomato is loads(dumps(Fruit.tomato))
|
||||
True
|
||||
|
||||
|
||||
Convenience API
|
||||
---------------
|
||||
|
||||
TODO: update to the new convenience API
|
||||
|
||||
You can also create enumerations using the convenience function ``make()``,
|
||||
which takes an iterable object or dictionary to provide the item names and
|
||||
values. ``make()`` is a module-level function.
|
||||
|
@ -447,7 +432,6 @@ Proposed variations
|
|||
Some variations were proposed during the discussions in the mailing list.
|
||||
Here's some of the more popular ones.
|
||||
|
||||
|
||||
Not having to specify values for enums
|
||||
--------------------------------------
|
||||
|
||||
|
@ -466,7 +450,6 @@ Cons: involves much magic in the implementation, which makes even the
|
|||
definition of such enums baffling when first seen. Besides, explicit is
|
||||
better than implicit.
|
||||
|
||||
|
||||
Using special names or forms to auto-assign enum values
|
||||
-------------------------------------------------------
|
||||
|
||||
|
@ -508,18 +491,24 @@ usages can be divided to two categories: user-code facing constants, and
|
|||
internal constants.
|
||||
|
||||
User-code facing constants like ``os.SEEK_*``, ``socket`` module constants,
|
||||
decimal rounding modes, HTML error codes could benefit from being enums had
|
||||
they been implemented this way from the beginning. At this point, however, at
|
||||
the risk of breaking user code (that relies on the constants' actual values
|
||||
rather than their meaning) such a change cannot be made. This does not mean
|
||||
that future uses in the stdlib can't use an enum for defining new user-code
|
||||
facing constants.
|
||||
decimal rounding modes and HTML error codes could require backwards
|
||||
compatibility since user code may expect integers. ``IntEnum`` as described
|
||||
above provides the required semantics; being a subclass of ``int``, it does not
|
||||
affect user code that expects integers, while on the other hand allowing
|
||||
printable representations for enumeration values::
|
||||
|
||||
>>> import socket
|
||||
>>> family = socket.AF_INET
|
||||
>>> family == 2
|
||||
True
|
||||
>>> print(family)
|
||||
SocketFamily.AF_INET
|
||||
|
||||
Internal constants are not seen by user code but are employed internally by
|
||||
stdlib modules. It appears that nothing should stand in the way of
|
||||
implementing such constants with enums. Some examples uncovered by a very
|
||||
partial skim through the stdlib: ``binhex``, ``imaplib``, ``http/client``,
|
||||
``urllib/robotparser``, ``idlelib``, ``concurrent.futures``, ``turtledemo``.
|
||||
stdlib modules. These can be implemented with ``Enum``. Some examples
|
||||
uncovered by a very partial skim through the stdlib: ``binhex``, ``imaplib``,
|
||||
``http/client``, ``urllib/robotparser``, ``idlelib``, ``concurrent.futures``,
|
||||
``turtledemo``.
|
||||
|
||||
In addition, looking at the code of the Twisted library, there are many use
|
||||
cases for replacing internal state constants with enums. The same can be said
|
||||
|
|
Loading…
Reference in New Issue