[Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library

Nikolaus Rath Nikolaus at rath.org
Sun Apr 28 02:38:23 CEST 2013


Steven D'Aprano <steve at pearwood.info> writes:
> I'm sorry, but all these suggestions are getting the API completely
> backwards by making the common case harder than the rare case.
>
> We're creating an Enum, right? So the *common case* is to populate it
> with enum values. 99% of the time, enumerated values will be all that
> we want from an enum. So that's the case that needs to be simple, not
> the rare case where you have a non enum value in an enum class.
>
> The common case (enum values in an Enum class) should be easy, and the
> rare cases (ordinary class-like attributes) possible.
>
> Explicit is better than implicit: if you want something to *not* be
> processed by the Enum metaclass, you have to explicitly mark it as
> special. Dunders excepted, because they *are* special enough to break
> the rules. Since dunders are reserved for Python, I'm happy with a
> rule that says that dunders cannot be set as enum values (at least not
> via the metaclass). Otherwise, everything inside an Enum class is
> treated as an enum value unless explicitly flagged as not.
>
> Here's a dirty hack that demonstrates what I'm talking about.
[...]
> class Example(metaclass=MetaEnum):
>     red = 1
>     blue = 2
>     green = lambda: 'good lord, even functions can be enums!'
>     def __init__(self, count=3):
>         self.count = count
>     food = skip('spam')
>     @skip
>     def spam(self):
>         return self.count * self.food


However, without knowing that the MetaEnum metaclass will do some magic
here, there's no way to know that there's anything special about red,
blue and green. So I think there's actually a lot of implicit stuff
happening here.

In contrast,

class Example(metaclass=MetaEnum):
     red = EnumValue(1)
     blue = EnumValue(2)
     green = EnumValue(lambda: 'good lord, even functions can be
     enums!')
     
     def __init__(self, count=3):
         self.count = count

     def spam(self):
         return self.count * self.food

Makes it very clear that red, blue will not be attributes of type int,
even if one has never heard of Enums or metaclasses before.

I don't think this syntax is making the common case hard. By the same
logic, you'd need to introduce C-style i++ postincrement because having
just "i += x" makes the common case with x=1 "hard" as well.


Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C



More information about the Python-Dev mailing list