Consistent formatting & cleanup, explicit namespacing of make. Updated todo
This commit is contained in:
parent
6f23bce51b
commit
5e8e6fa2d9
|
@ -64,8 +64,10 @@ Module & type name
|
|||
==================
|
||||
|
||||
We propose to add a module named ``enum`` to the standard library. The main
|
||||
type exposed by this module is ``Enum``.
|
||||
type exposed by this module is ``Enum``. Hence, to import the ``Enum`` type
|
||||
user code will run::
|
||||
|
||||
>>> from enum import Enum
|
||||
|
||||
Proposed semantics for the new enumeration type
|
||||
===============================================
|
||||
|
@ -76,8 +78,8 @@ Creating an Enum
|
|||
Enumerations are created using the class syntax, which makes them easy to read
|
||||
and write. Every enumeration value must have a unique integer value and the
|
||||
only restriction on their names is that they must be valid Python identifiers.
|
||||
To define an enumeration, derive from the Enum class and add attributes with
|
||||
assignment to their integer values.
|
||||
To define an enumeration, derive from the ``Enum`` class and add attributes with
|
||||
assignment to their integer values::
|
||||
|
||||
>>> from enum import Enum
|
||||
>>> class Colors(Enum):
|
||||
|
@ -85,7 +87,7 @@ assignment to their integer values.
|
|||
... green = 2
|
||||
... blue = 3
|
||||
|
||||
Enumeration values are compared by identity.
|
||||
Enumeration values are compared by identity::
|
||||
|
||||
>>> Colors.red is Colors.red
|
||||
True
|
||||
|
@ -96,17 +98,17 @@ Enumeration values are compared by identity.
|
|||
>>> Colors.blue is Colors.red
|
||||
False
|
||||
|
||||
Enumeration values have nice, human readable string representations...
|
||||
Enumeration values have nice, human readable string representations::
|
||||
|
||||
>>> print(Colors.red)
|
||||
Colors.red
|
||||
|
||||
...while their repr has more information.
|
||||
...while their repr has more information::
|
||||
|
||||
>>> print(repr(Colors.red))
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
|
||||
The enumeration value names are available through the class members.
|
||||
The enumeration value names are available through the class members::
|
||||
|
||||
>>> for member in Colors.__members__:
|
||||
... print(member)
|
||||
|
@ -115,13 +117,13 @@ The enumeration value names are available through the class members.
|
|||
blue
|
||||
|
||||
Let's say you wanted to encode an enumeration value in a database. You might
|
||||
want to get the enumeration class object from an enumeration value.
|
||||
want to get the enumeration class object from an enumeration value::
|
||||
|
||||
>>> cls = Colors.red.enum
|
||||
>>> print(cls.__name__)
|
||||
Colors
|
||||
|
||||
Enums also have a property that contains just their item name.
|
||||
Enums also have a property that contains just their item name::
|
||||
|
||||
>>> print(Colors.red.name)
|
||||
red
|
||||
|
@ -130,21 +132,21 @@ Enums also have a property that contains just their item name.
|
|||
>>> print(Colors.blue.name)
|
||||
blue
|
||||
|
||||
The str and repr of the enumeration class also provides useful information.
|
||||
The str and repr of the enumeration class also provides useful information::
|
||||
|
||||
>>> print(Colors)
|
||||
<Colors {red: 1, green: 2, blue: 3}>
|
||||
>>> print(repr(Colors))
|
||||
<Colors {red: 1, green: 2, blue: 3}>
|
||||
|
||||
You can extend previously defined Enums by subclassing.
|
||||
You can extend previously defined Enums by subclassing::
|
||||
|
||||
>>> class MoreColors(Colors):
|
||||
... pink = 4
|
||||
... cyan = 5
|
||||
|
||||
When extended in this way, the base enumeration's values are identical to the
|
||||
same named values in the derived class.
|
||||
same named values in the derived class::
|
||||
|
||||
>>> Colors.red is MoreColors.red
|
||||
True
|
||||
|
@ -153,7 +155,7 @@ same named values in the derived class.
|
|||
|
||||
However, these are not doing comparisons against the integer equivalent
|
||||
values, because if you define an enumeration with similar item names and
|
||||
integer values, they will not be identical.
|
||||
integer values, they will not be identical::
|
||||
|
||||
>>> class OtherColors(Enum):
|
||||
... red = 1
|
||||
|
@ -164,7 +166,7 @@ integer values, they will not be identical.
|
|||
>>> Colors.blue is not OtherColors.blue
|
||||
True
|
||||
|
||||
These enumeration values are not equal, nor do they hash equally.
|
||||
These enumeration values are not equal, nor do they hash equally::
|
||||
|
||||
>>> Colors.red == OtherColors.red
|
||||
False
|
||||
|
@ -172,7 +174,7 @@ These enumeration values are not equal, nor do they hash equally.
|
|||
2
|
||||
|
||||
Ordered comparisons between enumeration values are *not* supported. Enums are
|
||||
not integers!
|
||||
not integers::
|
||||
|
||||
>>> Colors.red < Colors.blue
|
||||
Traceback (most recent call last):
|
||||
|
@ -191,14 +193,14 @@ not integers!
|
|||
...
|
||||
NotImplementedError
|
||||
|
||||
Equality comparisons are defined though.
|
||||
Equality comparisons are defined though::
|
||||
|
||||
>>> Colors.blue == Colors.blue
|
||||
True
|
||||
>>> Colors.green != Colors.blue
|
||||
True
|
||||
|
||||
Enumeration values do not support ordered comparisons.
|
||||
Enumeration values do not support ordered comparisons::
|
||||
|
||||
>>> Colors.red < Colors.blue
|
||||
Traceback (most recent call last):
|
||||
|
@ -222,7 +224,7 @@ Enumeration values do not support ordered comparisons.
|
|||
NotImplementedError
|
||||
|
||||
While equality comparisons are allowed, comparisons against non-enumeration
|
||||
values will always compare not equal.
|
||||
values will always compare not equal::
|
||||
|
||||
>>> Colors.green == 2
|
||||
False
|
||||
|
@ -235,7 +237,7 @@ values will always compare not equal.
|
|||
|
||||
If you really want the integer equivalent values, you can convert enumeration
|
||||
values explicitly using the ``int()`` built-in. This is quite convenient for
|
||||
storing enums in a database for example.
|
||||
storing enums in a database for example::
|
||||
|
||||
>>> int(Colors.red)
|
||||
1
|
||||
|
@ -244,8 +246,8 @@ storing enums in a database for example.
|
|||
>>> int(Colors.blue)
|
||||
3
|
||||
|
||||
You can also convert back to the enumeration value by calling the Enum class,
|
||||
passing in the integer value for the item you want.
|
||||
You can also convert back to the enumeration value by calling the Enum subclass,
|
||||
passing in the integer value for the item you want::
|
||||
|
||||
>>> Colors(1)
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
|
@ -256,14 +258,14 @@ passing in the integer value for the item you want.
|
|||
>>> Colors(1) is Colors.red
|
||||
True
|
||||
|
||||
The Enum class also accepts the string name of the enumeration value.
|
||||
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.
|
||||
You get exceptions though, if you try to use invalid arguments::
|
||||
|
||||
>>> Colors('magenta')
|
||||
Traceback (most recent call last):
|
||||
|
@ -275,7 +277,7 @@ You get exceptions though, if you try to use invalid arguments.
|
|||
ValueError: 99
|
||||
|
||||
The Enum base class also supports getitem syntax, exactly equivalent to the
|
||||
class's call semantics.
|
||||
class's call semantics::
|
||||
|
||||
>>> Colors[1]
|
||||
<EnumValue: Colors.red [int=1]>
|
||||
|
@ -299,7 +301,7 @@ class's call semantics.
|
|||
ValueError: 99
|
||||
|
||||
The integer equivalent values serve another purpose. You may not define two
|
||||
enumeration values with the same integer value.
|
||||
enumeration values with the same integer value::
|
||||
|
||||
>>> class Bad(Enum):
|
||||
... cartman = 1
|
||||
|
@ -311,7 +313,7 @@ enumeration values with the same integer value.
|
|||
...
|
||||
TypeError: Multiple enum values: 3
|
||||
|
||||
You also may not duplicate values in derived enumerations.
|
||||
You also may not duplicate values in derived enumerations::
|
||||
|
||||
>>> class BadColors(Colors):
|
||||
... yellow = 4
|
||||
|
@ -321,14 +323,14 @@ You also may not duplicate values in derived enumerations.
|
|||
TypeError: Multiple enum values: 2
|
||||
|
||||
The Enum class support iteration. Enumeration values are returned in the
|
||||
sorted order of their integer equivalent values.
|
||||
sorted order of their integer equivalent values::
|
||||
|
||||
>>> [v.name for v in MoreColors]
|
||||
['red', 'green', 'blue', 'pink', 'cyan']
|
||||
>>> [int(v) for v in MoreColors]
|
||||
[1, 2, 3, 4, 5]
|
||||
|
||||
Enumeration values are hashable, so they can be used in dictionaries and sets.
|
||||
Enumeration values are hashable, so they can be used in dictionaries and sets::
|
||||
|
||||
>>> apples = {}
|
||||
>>> apples[Colors.red] = 'red delicious'
|
||||
|
@ -342,7 +344,7 @@ Enumeration values are hashable, so they can be used in dictionaries and sets.
|
|||
Pickling
|
||||
--------
|
||||
|
||||
Enumerations created with the class syntax can also be pickled and unpickled:
|
||||
Enumerations created with the class syntax can also be pickled and unpickled::
|
||||
|
||||
>>> from enum.tests.fruit import Fruit
|
||||
>>> from pickle import dumps, loads
|
||||
|
@ -358,25 +360,25 @@ which takes an iterable object or dictionary to provide the item names and
|
|||
values. ``make()`` is a static method.
|
||||
|
||||
The first argument to ``make()`` is the name of the enumeration, and it returns
|
||||
the so-named `Enum` subclass. The second argument is a `source` which can be
|
||||
either an iterable or a dictionary. In the most basic usage, `source` returns
|
||||
the so-named `Enum` subclass. The second argument is a *source* which can be
|
||||
either an iterable or a dictionary. In the most basic usage, *source* returns
|
||||
a sequence of strings which name the enumeration items. In this case, the
|
||||
values are automatically assigned starting from 1::
|
||||
|
||||
>>> from enum import make
|
||||
>>> make('Animals', ('ant', 'bee', 'cat', 'dog'))
|
||||
>>> import enum
|
||||
>>> enum.make('Animals', ('ant', 'bee', 'cat', 'dog'))
|
||||
<Animals {ant: 1, bee: 2, cat: 3, dog: 4}>
|
||||
|
||||
The items in source can also be 2-tuples, where the first item is the
|
||||
enumeration value name and the second is the integer value to assign to the
|
||||
value. If 2-tuples are used, all items must be 2-tuples.
|
||||
value. If 2-tuples are used, all items must be 2-tuples::
|
||||
|
||||
>>> def enumiter():
|
||||
... start = 1
|
||||
... while True:
|
||||
... yield start
|
||||
... start <<= 1
|
||||
>>> make('Flags', zip(list('abcdefg'), enumiter()))
|
||||
>>> enum.make('Flags', zip(list('abcdefg'), enumiter()))
|
||||
<Flags {a: 1, b: 2, c: 4, d: 8, e: 16, f: 32, g: 64}>
|
||||
|
||||
|
||||
|
@ -402,24 +404,24 @@ common values in derived classes are identical (a singleton model). While PEP
|
|||
complexity, though minimal, is hidden from users of the enumeration.
|
||||
|
||||
Unlike PEP 354, enumeration values can only be tested by identity comparison.
|
||||
This is to emphasis the fact that enumeration values are singletons, much like
|
||||
This is to emphasise the fact that enumeration values are singletons, much like
|
||||
``None``.
|
||||
|
||||
|
||||
Acknowledgments
|
||||
===============
|
||||
|
||||
The ``flufl.enum`` implementation is based on an example by Jeremy Hylton. It
|
||||
has been modified and extended by Barry Warsaw for use in the `GNU Mailman`_
|
||||
project. Ben Finney is the author of the earlier enumeration PEP 354.
|
||||
|
||||
.. _`GNU Mailman`: http://www.list.org
|
||||
This PEP describes the ``flufl.enum`` package by Barry Warsaw. ``flufl.enum``
|
||||
is based on an example by Jeremy Hylton. It has been modified and extended
|
||||
by Barry Warsaw for use in the GNU Mailman [#]_ project. Ben Finney is the
|
||||
author of the earlier enumeration PEP 354.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [#] http://mail.python.org/pipermail/python-ideas/2013-January/019003.html
|
||||
.. [#] http://mail.python.org/pipermail/python-ideas/2013-February/019373.html
|
||||
.. [#] http://www.list.org
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
@ -429,10 +431,15 @@ This document has been placed in the public domain.
|
|||
Todo
|
||||
====
|
||||
|
||||
* Mark PEP 354 "superseded by" this one
|
||||
* New package name within stdlib
|
||||
* ``from enum import make`` creates a not-very-descriptive "make" name. Maybe
|
||||
``make_enum`` or ``enum`` is better?
|
||||
* Mark PEP 354 "superseded by" this one, if accepted
|
||||
* New package name within stdlib - enum? (top-level)
|
||||
* "Convenience API" says "make() is a static method" - what does this mean?
|
||||
make seems to be a simple module-level function in the implementation.
|
||||
* For make, can we add an API like namedtuple's?
|
||||
make('Animals, 'ant bee cat dog')
|
||||
I.e. when make sees a string argument it splits it, making it similar to a
|
||||
tuple but with far less manual quote typing. OTOH, it just saves a ".split"
|
||||
so may not be worth the effort ?
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
|
|
Loading…
Reference in New Issue