2012-04-08 11 views
70

¿Existe alguna regla sobre qué clases de biblioteca integradas y estándar no son subclasables ("final")?¿Qué clases no se pueden subclasificar?

A partir de Python 3.3, aquí hay algunos ejemplos:

  • bool
  • function
  • operator.itemgetter
  • slice

encontré una question que se ocupa de la aplicación de clases "finales", ambas en C y Python puro.

Me gustaría entender qué razones pueden explicar por qué una clase se elige para ser "definitiva" en primer lugar.

+4

'NoneType' es otro ejemplo. – Duncan

+4

¿Se puede subclasificar una clase final en una implementación de Python en otra implementación? Espero que alguien pueda confirmar que nunca sucede. De lo contrario, el código escrito para una implementación puede romperse cuando se transfiere a otro (muy dolorosamente, también: imagínese si alguien subclasificó 'función', y ahora necesita refactorizar el código para evitar esta herencia). – max

+3

Tenga en cuenta que PyPy se niega a subclasificar los cuatro ejemplos, también ... aunque no tenga la restricción CPython. Pueden tener una razón documentada en su código base. –

Respuesta

23

Parece haber dos razones para que una clase sea "definitiva" en Python.

1. Violación de invariante de clase

clases que siguen patrón Singleton tiene un invariante que hay un número limitado (pre-determinado) de instancias. Cualquier violación de este invariante en una subclase será inconsistente con el intento de la clase, y no funcionaría correctamente. Ejemplos:

  • bool: True, False; ver Guido's comments
  • NoneType: None
  • NotImplementedType: NotImplemented
  • ellipsis: Ellipsis

Puede haber casos en que no sea el patrón Singleton en esta categoría, pero no estoy al tanto de ninguna.

2. Sin persuasiva caso de uso

Una clase implementado en C requiere trabajo adicional para permitir la creación de subclases (al menos en CPython). Hacer tal trabajo sin un caso de uso convincente no es muy atractivo, por lo que es menos probable que los voluntarios se presenten. Ejemplos:

Nota 1:

Al principio pensé que había casos de uso válidos, pero el interés simplemente insuficiente, en la subclasificación de function y operator.itemgetter. Gracias a @agf por señalar que los casos de uso ofrecidos here y here no son convincentes (consulte los comentarios de @agf a la pregunta).

Nota 2:

Mi preocupación es que otra aplicación Python accidentalmente podría permitir la subclasificación de una clase que es definitiva en CPython. Esto puede dar como resultado un código no portátil (un caso de uso puede ser débil, pero alguien aún puede escribir el código que las subclases function si Python lo admite). Esto puede resolverse marcando en la documentación de Python todas las clases de biblioteca incorporadas y estándar que no se pueden subclasificar, y requiriendo que todas las implementaciones sigan el comportamiento de CPython en ese sentido.

Nota 3:

El mensaje producido por CPython en todos los casos anteriores es:

TypeError: type 'bool' is not an acceptable base type 

Es bastante críptica, como numerosas preguntas sobre este tema muestran. Voy a enviar una sugerencia para agregar un párrafo a la documentación que explica las clases finales, y tal vez incluso cambiar el mensaje de error a:

TypeError: type 'bool' is final (non-extensible) 
+3

Por supuesto, si estuvieras escribiendo una simulación de Schrodinger's Cat, podrías subclasificar 'bool' para incluir' unknown' :-P es una broma – Endophage

+8

@Endophage: un Qbit ciertamente sería un tipo útil, pero no es una subcategoría de 'bool', de hecho, todo lo contrario, ¡cada valor booleano es un tipo de qbit! uno que sucede ser observado. Sin embargo, probablemente manejaría ese caso con '__subclasscheck__' y amigos. – SingleNegationElimination

+4

@TokenMacGuy excelente observación! Entonces, ¿por qué no tenemos una clase Qbit en Python que bool es una subclase de! ¡Exijo que así sea! :-P – Endophage

Cuestiones relacionadas