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

Reply via email to