PEP 435: initial values must be specified? Yes
On 05/05/2013 10:07 AM, � wrote:> I'm chiming in late, but am I the only one who's really bothered by the syntax?
class Color(Enum): red = 1 green = 2 blue = 3
No, you are not only one that's bothered by it. I tried it without assignments until I discovered that bugs are way too easy to introduce. The problem is a successful name lookup looks just like a name failure, but of course no error is raised and no new enum item is created: --> class Color(Enum): ... red, green, blue ... --> class MoreColor(Color): ... red, orange, yellow ... --> type(MoreColor.red) is MoreColor False --> MoreColor.orange <MoreColor.orange: 4> # value should be 5 About the closest you going to be able to get is something like: def e(_next=[1]): e, _next[0] = _next[0], _next[0] + 1 return e class Color(Enum): red = e() green = e() blue = e() and you can keep using `e()` for all your enumerations, since you don't care what actual value each enumeration member happens to get. -- ~Ethan~
On 6 May 2013 06:09, Ethan Furman <ethan@stoneleaf.us> wrote:
On 05/05/2013 10:07 AM, � wrote:> I'm chiming in late, but am I the only one who's really bothered by the syntax?
class Color(Enum): red = 1 green = 2 blue = 3
No, you are not only one that's bothered by it. I tried it without assignments until I discovered that bugs are way too easy to introduce. The problem is a successful name lookup looks just like a name failure, but of course no error is raised and no new enum item is created:
--> class Color(Enum): ... red, green, blue ...
--> class MoreColor(Color): ... red, orange, yellow ...
--> type(MoreColor.red) is MoreColor False
--> MoreColor.orange <MoreColor.orange: 4> # value should be 5
Actually, my implementation at https://bitbucket.org/magao/enum (the one mentioned in the PEP) does detect MoreColor.red as a duplicate. It's possible to do it, but it's definitely black magic and also involves use of sys._getframe() for more than just getting module name.
from enum import Enum class Color(Enum): ... red, green, blue ... class MoreColor(Color): ... red, orange, yellow ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File ".\enum.py", line 388, in __new__ raise AttributeError("Duplicate enum key '%s.%s' (overriding '%s')" % (result.__name__, v.key, k eys[v.key])) AttributeError: Duplicate enum key 'MoreColor.red' (overriding 'Color.red')
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think. class Color(AutoIntEnum): red = ... green = ... blue = ... Not as pretty, but ends up being less magical. Tim Delaney
On Sun, May 5, 2013 at 2:55 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
Specifically what do you want the PEP to promise? -- --Guido van Rossum (python.org/~guido)
On 6 May 2013 08:00, Guido van Rossum <guido@python.org> wrote:
On Sun, May 5, 2013 at 2:55 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
Specifically what do you want the PEP to promise?
It was mentioned in the other threads, but the requirement is either: 1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__. OR 2. A way for subclasses of Enum to modify the value before it's assigned to the actual enum - see the PEP 435 reference implementation - discussion thread where I modified the reference implementation to give enum instances 2-phase construction, passing the value to Enum.__init__. This way is more limited, as you need to use an appropriate mix-in type which puts certain constraints on the behaviour of the enum instances (e.g. they *have* to be int instances for auto-numbering). The implementation is also more complex, and as noted in that thread, __init__ might not be appropriate for an Enum. Tim Delaney
On Sun, May 5, 2013 at 3:34 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
On 6 May 2013 08:00, Guido van Rossum <guido@python.org> wrote:
On Sun, May 5, 2013 at 2:55 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
Specifically what do you want the PEP to promise?
It was mentioned in the other threads, but the requirement is either:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
OR
2. A way for subclasses of Enum to modify the value before it's assigned to the actual enum - see the PEP 435 reference implementation - discussion thread where I modified the reference implementation to give enum instances 2-phase construction, passing the value to Enum.__init__. This way is more limited, as you need to use an appropriate mix-in type which puts certain constraints on the behaviour of the enum instances (e.g. they *have* to be int instances for auto-numbering). The implementation is also more complex, and as noted in that thread, __init__ might not be appropriate for an Enum.
I'll let Eli or Ethan respond to this. It sounds fine to me to support you with some kind of hook in the spec, even though I personally would rather assign my enum values explicitly (I'm old-fashioned that way :-). -- --Guido van Rossum (python.org/~guido)
On May 05, 2013, at 03:43 PM, Guido van Rossum wrote:
I'll let Eli or Ethan respond to this. It sounds fine to me to support you with some kind of hook in the spec, even though I personally would rather assign my enum values explicitly (I'm old-fashioned that way :-).
Assuming the picklability of functional API created Enums is fixed (sorry, another threadsplosion still awaits me), if you *really* have to have autonumbering, use the functional API. IMHO, the class API doesn't need them. -Barry
On Sun, May 5, 2013 at 3:34 PM, Tim Delaney <timothy.c.delaney@gmail.com>wrote:
On 6 May 2013 08:00, Guido van Rossum <guido@python.org> wrote:
On Sun, May 5, 2013 at 2:55 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
Specifically what do you want the PEP to promise?
It was mentioned in the other threads, but the requirement is either:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
OR
2. A way for subclasses of Enum to modify the value before it's assigned to the actual enum - see the PEP 435 reference implementation - discussion thread where I modified the reference implementation to give enum instances 2-phase construction, passing the value to Enum.__init__. This way is more limited, as you need to use an appropriate mix-in type which puts certain constraints on the behaviour of the enum instances (e.g. they *have* to be int instances for auto-numbering). The implementation is also more complex, and as noted in that thread, __init__ might not be appropriate for an Enum.
So your preferred solution is (1), which requires exposing the metaclass and an attribute publicly? I have to ask - to what end? What is the goal of this? To have an AutoNumberedEnum which is guaranteed to be compatible with stdlib's Enum? IMHO this goal is not important enough, and I'm not aware of other stdlib modules that go to such lengths exposing implementation details publicly (but I'd be happy to be educated on this!) Assuming ref435 goes as-is into stdlib in 3.4, can't you just assume its implementation? And then change yours if it changes? Python's stdlib doesn't change that often, but if we do want to change the implementation at some point, this documented piece of internals is surely going to be in the way. Why should the future malleability of a stdlib module be sacrificed for the sake of this extension? Eli
On Sun, May 5, 2013 at 3:55 PM, Eli Bendersky <eliben@gmail.com> wrote:
On Sun, May 5, 2013 at 3:34 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
On 6 May 2013 08:00, Guido van Rossum <guido@python.org> wrote:
On Sun, May 5, 2013 at 2:55 PM, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
Specifically what do you want the PEP to promise?
It was mentioned in the other threads, but the requirement is either:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
OR
2. A way for subclasses of Enum to modify the value before it's assigned to the actual enum - see the PEP 435 reference implementation - discussion thread where I modified the reference implementation to give enum instances 2-phase construction, passing the value to Enum.__init__. This way is more limited, as you need to use an appropriate mix-in type which puts certain constraints on the behaviour of the enum instances (e.g. they *have* to be int instances for auto-numbering). The implementation is also more complex, and as noted in that thread, __init__ might not be appropriate for an Enum.
So your preferred solution is (1), which requires exposing the metaclass and an attribute publicly? I have to ask - to what end? What is the goal of this? To have an AutoNumberedEnum which is guaranteed to be compatible with stdlib's Enum?
IMHO this goal is not important enough, and I'm not aware of other stdlib modules that go to such lengths exposing implementation details publicly (but I'd be happy to be educated on this!)
Assuming ref435 goes as-is into stdlib in 3.4, can't you just assume its implementation? And then change yours if it changes? Python's stdlib doesn't change that often, but if we do want to change the implementation at some point, this documented piece of internals is surely going to be in the way. Why should the future malleability of a stdlib module be sacrificed for the sake of this extension?
Hm. Either you should argue much more strongly against Tim's solution, or you should expose the implementation detail he needs. Recommending that he should just use an internal detail of the implementation and hope it never changes sounds like encouraging a bad habit. It also seems you're contradicting yourself by saying that the code is unlikely to change and at the same time wanting to reserve the right to change it. Also note that the future malleability of a stdlib module is affected even by 3rd party use that goes beyond the documented API -- it all depends on a pragmatic weighing of how important a proposed change is against how likely it is to break existing use, and there are plenty of examples in the past where we have resisted changing an implementation detail because it would break too much code. If you really don't want to guarantee this part of the implementation, you should recommend that Tim just copy all of ref435. TBH I don't see what deriving AutoNumberEnum from the stdlib Enum class buy him except that he has to maintain less code. I don't expect there to be a lot of opportunities anywhere for writing isinstance(x, Enum). -- --Guido van Rossum (python.org/~guido)
It was mentioned in the other threads, but the requirement is either:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
OR
2. A way for subclasses of Enum to modify the value before it's assigned to the actual enum - see the PEP 435 reference implementation - discussion thread where I modified the reference implementation to give enum instances 2-phase construction, passing the value to Enum.__init__. This way is more limited, as you need to use an appropriate mix-in type which puts certain constraints on the behaviour of the enum instances (e.g. they *have* to be int instances for auto-numbering). The implementation is also more complex, and as noted in that thread, __init__ might not be appropriate for an Enum.
So your preferred solution is (1), which requires exposing the metaclass and an attribute publicly? I have to ask - to what end? What is the goal of this? To have an AutoNumberedEnum which is guaranteed to be compatible with stdlib's Enum?
IMHO this goal is not important enough, and I'm not aware of other stdlib modules that go to such lengths exposing implementation details publicly (but I'd be happy to be educated on this!)
Assuming ref435 goes as-is into stdlib in 3.4, can't you just assume its implementation? And then change yours if it changes? Python's stdlib doesn't change that often, but if we do want to change the implementation at some point, this documented piece of internals is surely going to be in the way. Why should the future malleability of a stdlib module be sacrificed for the sake of this extension?
Hm. Either you should argue much more strongly against Tim's solution, or you should expose the implementation detail he needs. Recommending that he should just use an internal detail of the implementation and hope it never changes sounds like encouraging a bad habit. It also seems you're contradicting yourself by saying that the code is unlikely to change and at the same time wanting to reserve the right to change it.
OK, then I'll say without contradictions that I don't expect the implementation of Enum to be stable at this point. We don't even *have* an implementation yet. All we have is some (pretty good!) code Ethan wrote and I only partially reviewed. The final implementation may be completely different, and then again we may want to change it in light of new input. I wouldn't want to constrain ourselves at this point. Perhaps when 3.4 is branched will be a point in time in which this can be re-visited. Makes sense?
Also note that the future malleability of a stdlib module is affected even by 3rd party use that goes beyond the documented API -- it all depends on a pragmatic weighing of how important a proposed change is against how likely it is to break existing use, and there are plenty of examples in the past where we have resisted changing an implementation detail because it would break too much code.
Agreed, but if we document these details, we're forever bound, pragmatic weighing notwithstanding. Also, in this particular case if auto-numbered enums in the class API are deemed super-useful we may end up incorporating a syntax for them anyway, which will render the external module obsolete.
If you really don't want to guarantee this part of the implementation, you should recommend that Tim just copy all of ref435. TBH I don't see what deriving AutoNumberEnum from the stdlib Enum class buy him except that he has to maintain less code. I don't expect there to be a lot of opportunities anywhere for writing isinstance(x, Enum).
That's what I was trying to say, I guess. Even if the chance of changing the implementation of Enum is pretty low (after 3.4 I mean, before that it's pretty damn high), I don't think that restricting ourselves here is justified by Tim's maintaining less code in his external module. With all due respect, of course ;-) Eli
On 6 May 2013 08:55, Eli Bendersky <eliben@gmail.com> wrote:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
So your preferred solution is (1), which requires exposing the metaclass and an attribute publicly? I have to ask - to what end? What is the goal of this? To have an AutoNumberedEnum which is guaranteed to be compatible with stdlib's Enum?
My preferred solution is 1 (for the reason mentioned above) but it does not require exposing the metaclass publically (that's obtainable via type(Enum)). It does require a way to get the enum names before calling the base metaclass __new__, but that does not necessarily imply that I'm advocating exposing _enum_names (or at least, not directly). My preferred way would probably be a note that the dictionary returned from the enum metaclass __prepare__ implements an enum_names() or maybe __enum_names__() method which returns an iterator over the enum instance names in definition order. The way this is implemented by the dictionary would be an implementation detail. The enum metaclass __new__ needs access to the enum instance names in definition order, so I think making it easily available to enum metaclass subclasses as well just makes sense. Tim Delaney
On 05/05/2013 04:14 PM, Tim Delaney wrote:
1. That the dictionary returned from <enum metaclass>.__prepare__ provide a way to obtain the enum instance names once it's been populated (e.g. once it's been passed as the classdict to __new__). The reference implementation provides a _enum_names list attribute. The enum names need to be available to a metaclass subclass before calling the base metaclass __new__.
[...]
My preferred solution is 1 (for the reason mentioned above) but it does not require exposing the metaclass publically (that's obtainable via type(Enum)). It does require a way to get the enum names before calling the base metaclass __new__, but that does not necessarily imply that I'm advocating exposing _enum_names (or at least, not directly).
My preferred way would probably be a note that the dictionary returned from the enum metaclass __prepare__ implements an enum_names() or maybe __enum_names__() method which returns an iterator over the enum instance names in definition order. The way this is implemented by the dictionary would be an implementation detail.
I like having an __enum_names__() that returns a list or tuple of (name, value) pairs in definition order. -- ~Ethan~
On 05/05/2013 02:55 PM, Tim Delaney wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
class Color(AutoIntEnum): red = ... green = ... blue = ...
Will this do? class AutoNumber(Enum): def __new__(cls): value = len(cls.__enum_info__) + 1 obj = object.__new__(cls) obj._value = value return obj def __int__(self): return self._value class Color(AutoNumber): red = () green = () blue = () -- ~Ethan~
On 7 May 2013 12:29, Ethan Furman <ethan@stoneleaf.us> wrote:
On 05/05/2013 02:55 PM, Tim Delaney wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
class Color(AutoIntEnum): red = ... green = ... blue = ...
Will this do?
class AutoNumber(Enum): def __new__(cls): value = len(cls.__enum_info__) + 1 obj = object.__new__(cls) obj._value = value return obj def __int__(self): return self._value class Color(AutoNumber): red = () green = () blue = ()
Considering that doesn't actually work with the reference implementation (AutoNumber.__new__ is never called) ... no. print(Color.red._value) print(int(Color.red)) ---------- Run Python3 ---------- () Traceback (most recent call last): File "D:\home\repos\mercurial\ref435\ref435.py", line 292, in <module> print(int(Color.red)) TypeError: __int__ returned non-int (type tuple) Plus I would not want to use the empty tuple for the purpose - at least ... implies something ongoing. Tim Delaney
On 05/06/2013 07:58 PM, Tim Delaney wrote:
Considering that doesn't actually work with the reference implementation (AutoNumber.__new__ is never called) ... no.
Two points: 1) Did you grab the latest code? That exact implementation passes in the tests. 2) You can write your __new__ however you want -- use ... ! ;) -- ~Ethan~
On 7 May 2013 14:54, Ethan Furman <ethan@stoneleaf.us> wrote:
On 05/06/2013 07:58 PM, Tim Delaney wrote:
Considering that doesn't actually work with the reference implementation (AutoNumber.__new__ is never called) ... no.
Two points:
1) Did you grab the latest code? That exact implementation passes in the tests.
D'oh! I had my default path being my forked repo ... so didn't see the changes. BTW I can't see how that exact implementation passes ... not enough parameters declared in AutoNumber.__new__ ...
2) You can write your __new__ however you want -- use ... ! ;)
class AutoNumber(Enum): def __new__(cls, value): if value is Ellipsis: try: value = cls._auto_number except AttributeError: value = cls._auto_number = 0 else: cls._auto_number = int(value) obj = object.__new__(cls) obj._value = value cls._auto_number += 1 return obj def __int__(self): return self._value class Color(AutoNumber): red = ... green = 3 blue = ... print(repr(Color.red)) print(repr(Color.green)) print(repr(Color.blue)) ---------- Run Python3 ---------- <Color.red: 0> <Color.green: 3> <Color.blue: 4> Unfortunately, if you subclass AutoNumber from IntEnum it breaks. ---------- Run Python3 ---------- Traceback (most recent call last): File "D:\home\repos\mercurial\ref435\ref435.py", line 346, in <module> class Color(AutoNumber): File "D:\home\repos\mercurial\ref435\ref435.py", line 184, in __new__ enum_item = __new__(enum_class, *args) TypeError: int() argument must be a string or a number, not 'ellipsis' I would probably also suggest 2 changes: 1. Set enum_item._name before calling enum_item.__init__. 2. Don't pass any arguments to enum_item.__init__ - the value should be set in enum_item.__new__. Tim Delaney
On 7 May 2013 15:14, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
D'oh! I had my default path being my forked repo ... so didn't see the changes. BTW I can't see how that exact implementation passes ... not enough parameters declared in AutoNumber.__new__ ...
Sorry - my fault again - I'd already changed () to ... Tim Delaney
On 7 May 2013 15:14, Tim Delaney <timothy.c.delaney@gmail.com> wrote:
Unfortunately, if you subclass AutoNumber from IntEnum it breaks.
---------- Run Python3 ---------- Traceback (most recent call last): File "D:\home\repos\mercurial\ref435\ref435.py", line 346, in <module> class Color(AutoNumber): File "D:\home\repos\mercurial\ref435\ref435.py", line 184, in __new__ enum_item = __new__(enum_class, *args) TypeError: int() argument must be a string or a number, not 'ellipsis'
Or using your exact implementation, but subclassing AutoNumber from IntEnum: class AutoNumber(IntEnum): def __new__(cls): value = len(cls.__enum_info__) + 1 obj = object.__new__(cls) obj._value = value return obj def __int__(self): return self._value class Color(AutoNumber): red = () green = () blue = () print(repr(Color.red)) ---------- Run Python3 ---------- <Color.red: ()> Tim Delaney
On 05/06/2013 10:18 PM, Tim Delaney wrote:
On 7 May 2013 15:14, Tim Delaney <timothy.c.delaney@gmail.com <mailto:timothy.c.delaney@gmail.com>> wrote:
Unfortunately, if you subclass AutoNumber from IntEnum it breaks.
---------- Run Python3 ---------- Traceback (most recent call last): File "D:\home\repos\mercurial\ref435\ref435.py", line 346, in <module> class Color(AutoNumber): File "D:\home\repos\mercurial\ref435\ref435.py", line 184, in __new__ enum_item = __new__(enum_class, *args) TypeError: int() argument must be a string or a number, not 'ellipsis'
Or using your exact implementation, but subclassing AutoNumber from IntEnum:
class AutoNumber(IntEnum): def __new__(cls): value = len(cls.__enum_info__) + 1 obj = object.__new__(cls) obj._value = value return obj def __int__(self): return self._value class Color(AutoNumber): red = () green = () blue = ()
print(repr(Color.red))
---------- Run Python3 ---------- <Color.red: ()>
Thanks for the test case. It now passes. -- ~Ethan~
On 5/6/2013 7:58 PM, Tim Delaney wrote:
On 7 May 2013 12:29, Ethan Furman <ethan@stoneleaf.us <mailto:ethan@stoneleaf.us>> wrote:
On 05/05/2013 02:55 PM, Tim Delaney wrote:
So long as I can get one of the requirements documented to implement an auto-number syntax I'll be happy enough with stdlib enums I think.
class Color(AutoIntEnum): red = ... green = ... blue = ...
Will this do?
class AutoNumber(Enum): def __new__(cls): value = len(cls.__enum_info__) + 1 obj = object.__new__(cls) obj._value = value return obj def __int__(self): return self._value class Color(AutoNumber): red = () green = () blue = ()
Considering that doesn't actually work with the reference implementation (AutoNumber.__new__ is never called) ... no.
Maybe you should have tried with the latest version of the reference implementation, where Ethan kindly fixed the reference implementation to work better with NamedInt (per my thread "ref impl disc 2") and apparently also with the above class's __new__...
print(Color.red._value) print(int(Color.red))
---------- Run Python3 ---------- () Traceback (most recent call last): File "D:\home\repos\mercurial\ref435\ref435.py", line 292, in <module> print(int(Color.red)) TypeError: __int__ returned non-int (type tuple)
Plus I would not want to use the empty tuple for the purpose - at least ... implies something ongoing.
Why not? For classes derived from Enum, having __new__, the value/tuple assigned to the enumeration member becomes the set of parameters to __new__... so why would you want to provide a parameter? Well, you could, with a minor tweak. If you don't like Ethan's AutoNumber class, you can now write your own, like the following one that I derived from his, but to use your preferred ... class AutoNumber(Enum): def __new__(cls, parm): obj = object.__new__(cls) if parm is ...: value = len(cls.__enum_info__) + 1 obj._value = value else: obj._value = parm return obj def __int__(self): return self._value class Color(AutoNumber): red = ... green = ... blue = 7 purple = ... print ( Color.red, repr( Color.red )) print ( Color.green, repr( Color.green )) print ( Color.blue, repr( Color.blue )) print ( Color.purple, repr( Color.purple )) Since you want to provide a parameter, I decided in my example AutoNumber class that I would use ... as a flag to use his count, and anything else would be an actual value for the enumeration member. You could do whatever else you like, of course, should you write your own, including using someone's suggested itertools.count()
Ethan Furman wrote:
--> class Color(Enum): ... red, green, blue ...
--> class MoreColor(Color): ... red, orange, yellow ...
--> type(MoreColor.red) is MoreColor False
This argument no longer applies, since we're not allowing enums to be extended.
class Color(Enum): red = e() green = e() blue = e()
and you can keep using `e()` for all your enumerations, since you don't care what actual value each enumeration member happens to get.
I don't think it's true that people wanting auto-numbering don't care what values they get. Rather, they probably want ordinal values assigned separately and consecutively for each type, as in every other language I'm aware of that provides auto-numbered enums. If you *really* don't care what the values are, there's no need for the items to have values at all. -- Greg
On 05/05/2013 04:57 PM, Greg Ewing wrote:
Ethan Furman wrote:
--> class Color(Enum): ... red, green, blue ...
--> class MoreColor(Color): ... red, orange, yellow ...
--> type(MoreColor.red) is MoreColor False
This argument no longer applies, since we're not allowing enums to be extended.
Actually, it does: --> class Color(Enum): ... black, red, green, blue, cyan, magenta, yellow, black # oops! -- ~Ethan~
Am 05.05.2013 22:09, schrieb Ethan Furman:
About the closest you going to be able to get is something like:
def e(_next=[1]): e, _next[0] = _next[0], _next[0] + 1 return e
class Color(Enum): red = e() green = e() blue = e()
Uh, that's surely more nicely spelled as "e = itertools.count()"? Georg
On 05/06/2013 10:48 AM, Georg Brandl wrote:
Am 05.05.2013 22:09, schrieb Ethan Furman:
About the closest you going to be able to get is something like:
def e(_next=[1]): e, _next[0] = _next[0], _next[0] + 1 return e
class Color(Enum): red = e() green = e() blue = e()
Uh, that's surely more nicely spelled as "e = itertools.count()"?
Why, yes, I believe it is. :) -- ~Ethan~
participants (8)
-
Barry Warsaw
-
Eli Bendersky
-
Ethan Furman
-
Georg Brandl
-
Glenn Linderman
-
Greg Ewing
-
Guido van Rossum
-
Tim Delaney