La clase Python hereda el objeto.

¿Hay alguna razón para que una statement de clase herede de un object ?

Acabo de encontrar un código que hace esto y no puedo encontrar una buena razón para ello.

 class MyClass(object): # class code follows... 

¿Hay alguna razón para que una statement de clase herede de un object ?

tl; dr: En Python 3, aparte de la compatibilidad entre Python 2 y 3, no hay razón . En Python 2, muchas razones .


Historia de Python 2.x:

En Python 2.x (desde 2.2 en adelante) hay dos estilos de clases dependiendo de la presencia o ausencia de un object como clase base:

  1. Clases de estilo “clásico” : no tienen object como clase base:

     >>> class ClassicSpam: # no base class ... pass >>> ClassicSpam.__bases__ () 
  2. “nuevas” clases de estilo : tienen, directa o indirectamente (por ejemplo, heredar de un tipo incorporado ), object como clase base:

     >>> class NewSpam(object): # directly inherit from object ... pass >>> NewSpam.__bases__ (,) >>> class IntSpam(int): # indirectly inherit from object... ... pass >>> IntSpam.__bases__ (,) >>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object (,) 

Sin lugar a dudas, al escribir una clase siempre querrá ir a clases de nuevo estilo. Las ventajas de hacerlo son numerosas, para enumerar algunas de ellas:

  • Soporte para descriptores . Específicamente, las siguientes construcciones son posibles con descriptores:

    1. classmethod : método que recibe la clase como un argumento implícito en lugar de la instancia.
    2. staticmethod : método que no recibe el argumento implícito self como primer argumento.
    3. propiedades con property : crea funciones para gestionar la obtención, configuración y eliminación de un atributo.
    4. __slots__ : Guarda los consumos de memoria de una clase y también resulta en un acceso a atributos más rápido. Por supuesto, sí impone limitaciones .
  • El método estático __new__ : le permite personalizar cómo se crean las nuevas instancias de clase.

  • Orden de resolución de métodos (MRO) : en qué orden se buscarán las clases base de una clase al intentar resolver a qué método llamar.

  • Relacionado con MRO, super llamadas . Ver también, super() considerado super.

Si no hereda de object , olvídese de estos. Aquí puede encontrar una descripción más exhaustiva de las viñetas anteriores junto con otras ventajas de las “nuevas” clases de estilo.

Una de las desventajas de las clases de nuevo estilo es que la clase en sí misma requiere más memoria. Sin embargo, a menos que esté creando muchos objetos de clase, dudo que esto sea un problema y que sea un hundimiento negativo en un mar de aspectos positivos.


Historia de Python 3.x:

En Python 3, las cosas están simplificadas. Solo existen clases de nuevo estilo (referidas simplemente como clases), por lo tanto, la única diferencia en la adición de object requiere que escriba 8 caracteres más. Esta:

 class ClassicSpam: pass 

Es completamente equivalente (aparte de su nombre 🙂 a esto:

 class NewSpam(object): pass 

ya esto:

 class Spam(): pass 

Todos tienen object en sus __bases__ .

 >>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}] [True, True, True] 

¿Entonces, qué debería hacer?

En Python 2: siempre se hereda de un object explícitamente . Consigue los beneficios.

En Python 3: herede del object si está escribiendo código que intenta ser agnóstico de Python, es decir, debe funcionar tanto en Python 2 como en Python 3. De lo contrario, no hay ninguna diferencia, ya que Python lo inserta. usted detrás de las escenas.

Python 3.x:
class MyClass(object): = clase de nuevo estilo
class MyClass: = clase de estilo nuevo (se hereda implícitamente del objeto)

Python 2.x:
class MyClass(object): = clase de nuevo estilo
class MyClass: = OLD-STYLE CLASS

Explicación:

Al definir clases base en Python 3.x, se le permite eliminar el objeto de la definición. Sin embargo, esto puede abrir la puerta para un problema realmente difícil de rastrear …

Python introdujo clases de nuevo estilo en Python 2.2, y ahora las clases de estilo antiguo son bastante antiguas. La discusión de las clases de estilo antiguo está oculta en los documentos 2.x , y no existe en los documentos 3.x.

El problema es que la syntax para las clases de estilo antiguo en Python 2.x es la misma que la syntax alternativa para las clases de estilo nuevo en Python 3.x. Python 2.x todavía se usa mucho (por ejemplo, GAE, Web2Py), y cualquier código (o codificador) que, sin saberlo, incluya definiciones de clase de estilo 3.x en el código 2.x, terminará con algunos objetos base muy obsoletos. Y debido a que las clases de estilo antiguo no están en el radar de nadie, es probable que no sepan qué les golpeó.

Así que simplemente explíquelo a lo largo y ahorre a los desarrolladores 2.x las lágrimas.

Sí, este es un objeto de “nuevo estilo”. Fue una característica introducida en python2.2.

Los objetos de estilo nuevo tienen un modelo de objeto diferente al de los objetos clásicos, y algunas cosas no funcionarán correctamente con objetos de estilo antiguo, por ejemplo, super() , @property y descriptores. Vea este artículo para una buena descripción de lo que es una nueva clase de estilo.

Enlace SO para una descripción de las diferencias: ¿Cuál es la diferencia entre el estilo antiguo y las clases de estilo nuevo en Python?

Historia de Learn Python the Hard Way :

La versión original de Python de una clase se rompió de muchas maneras serias. En el momento en que se reconoció este error, ya era demasiado tarde y tenían que soportarlo. Para solucionar el problema, necesitaban un estilo de “nueva clase” para que las “clases antiguas” siguieran funcionando, pero se puede usar la nueva versión más correcta.

Decidieron que usarían una palabra “objeto”, en minúsculas, para ser la “clase” de la que se hereda para formar una clase. Es confuso, pero una clase hereda de la clase llamada “objeto” para crear una clase, pero no es un objeto en realidad es una clase, pero no olvide heredar de un objeto.

También para dejarte saber cuál es la diferencia entre las clases de estilo nuevo y las clases de estilo antiguo, es que las clases de estilo nuevo siempre heredan de la clase de object o de otra clase que heredó del object :

 class NewStyle(object): pass 

Otro ejemplo es:

 class AnotherExampleOfNewStyle(NewStyle): pass 

Mientras que una clase base de estilo antiguo se ve así:

 class OldStyle(): pass 

Y una clase de niños de estilo antiguo se ve así:

 class OldStyleSubclass(OldStyle): pass 

Puede ver que una clase base de estilo antiguo no se hereda de ninguna otra clase, sin embargo, las clases de estilo antiguo pueden, por supuesto, heredarse unas de otras. La herencia del objeto garantiza que cierta funcionalidad está disponible en cada clase de Python. Nuevas clases de estilo fueron introducidas en Python 2.2

Sí, es histórico . Sin él, crea una clase de estilo antiguo.

Si usa type() en un objeto de estilo antiguo, simplemente obtiene “instancia”. En un objeto de nuevo estilo obtienes su clase.

La syntax de la statement de creación de clase:

 class (superclass): #code follows 

En ausencia de otras superclases de las que desea heredar específicamente, la superclass siempre debe ser un object , que es la raíz de todas las clases en Python.

object es técnicamente la raíz de las clases de “nuevo estilo” en Python. Pero las clases de nuevo estilo de hoy son tan buenas como el único estilo de clases.

Pero, si no usa explícitamente la palabra object al crear clases, entonces, como mencionan otros, Python 3.x hereda implícitamente de la superclase del object . Pero supongo que explícito siempre es mejor que implícito (infierno)

Referencia