On 30/04/13 03:01, Guido van Rossum wrote:
Oh dear, this is actually a mess. I don't want MoreColor.red and
Color.red to be distinct objects, but then the isinstance() checks
will become confusing. If we don't override isinstance(), we'll get
not isinstance(Color.red, MoreColor)
isinstance(MoreColor.yellow, Color)
This would be pretty backwards.
Why is that backwards? MoreColor is a subclass of Color, so instances of
MoreColor are instances of Color, but instances of Color are not instances of
MoreColor. That's normal behaviour for subclasses. (All cats are mammals, but
not all mammals are cats.)
The only "funny" thing about this is that enumeration values of a Enum are only
instances of that Enum if they are declared inside that Enum, and as far as I'm concerned
that's not especially funny at all. So:
Color declares red, so Color.red is a Color.
MoreColor does not declare red, it merely inherits it from Color, so
MoreColor.red is Color.red which is not a MoreColor.
This leads to a simple rule:
Enum values are either instances of the enum they are defined in, or instances
of the parent class they are inherited from.
If the user doesn't like that, they're free to not subclass Enums :-)
I Ggoogled "enum subclassing" and found this StackOverflow article
explaining why you can't subclass enums in Java:
http://stackoverflow.com/questions/4604978/subclassing-an-enum which
refers to this more elaborate answer:
http://stackoverflow.com/questions/3427947/enumeration-inheritence-in-java/3428050#3428050
The first link says:
"And generally, a proper subclass is a specialization of its superclass."
and gives the Liskov Substitution Principle as the reason for prohibiting
subclassing. LSP is a very useful principle, but it is not the only model for
subclassing. That's why it's called a *principle* and not the Liskov
Substitution *Law*.
(Yes, I stole that from Raymond Hettinger's talk on subclassing at PyCon.)
I think that the ability to extend enums with new ones, without duplicating
code, is more important for enums than satisfying LSP. The common use-cases for
enums do not lend itself to subtyping in the Liskov sense.
E.g. if I have a function that expects a Color red/blue/green enum, and I
subclass it to give MoreColor yellow, I can't expect the function to suddenly
recognise yellow. So I'm not going to use subclassing in this case, because it
can't work.
But I will use subclassing to reuse values: if I have a function that expects
red/blue/green/yellow, and red/blue/green are already defined in Color, I'll
want to reuse them rather than duplicate them. Hence I will subclass Color
specifically to extend it, not to specialise it.
The second link quotes:
"For the most part, extensibility of enums turns out to be a bad idea. It is
confusing that elements of an extension type are instances of the base type and not vice
versa."
Confusing for who, and why?
You're going to confuse *somebody* no matter what you do. Either:
- confuse people who try to subclass enums, and can't; or
- confuse people who try to subclass enums, and can, but then get confused by
the result.
--
Steven
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com