¿Por qué las clases de Python heredan objetos?

Resuelto tjvr asked hace 13 años • 6 respuestas

¿ Por qué hereda la siguiente declaración de clase object?

class MyClass(object):
    ...
tjvr avatar Oct 25 '10 21:10 tjvr
Aceptado

¿ Hay alguna razón para heredar una declaración de clase object?

En Python 3, aparte de la compatibilidad entre Python 2 y 3, no hay motivo . En Python 2, hay 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 objectuna clase base:

  1. Clases de estilo "clásico" : no tienen objectcomo clase base:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. Clases de estilo "nuevas" : tienen, directa o indirectamente (por ejemplo, heredadas de un tipo incorporado ), objectcomo clase base:

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

Sin duda, al escribir una clase siempre querrás optar por clases de nuevo estilo. Las ventajas de hacerlo son numerosas, por 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 argumento implícito en lugar de la instancia.
    2. staticmethod: método que no recibe el argumento implícito selfcomo primer argumento.
    3. propiedades con property: crea funciones para gestionar la obtención, configuración y eliminación de un atributo.
    4. __slots__: Ahorra consumo de memoria de una clase y también da como resultado un acceso a atributos más rápido. Por supuesto, impone limitaciones .
  • El __new__método estático: le permite personalizar cómo se crean 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, superllamadas . Ver también, super()considerado súper.

Si no heredas de object, olvídate de estos. Puede encontrar una descripción más exhaustiva de los puntos anteriores junto con otras ventajas de las "nuevas" clases de estilo aquí .

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


Historia de Python 3.x:

En Python 3, las cosas se simplifican. Sólo existen clases de nuevo estilo (a las que se hace referencia simplemente como clases), por lo que la única diferencia al agregar objectes que requiere que escriba 8 caracteres más. Este:

class ClassicSpam:
    pass

es completamente equivalente (aparte de su nombre :-) a esto:

class NewSpam(object):
     pass

y a esto:

class Spam():
    pass

Todos tienen objecten su __bases__.

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

¿Entonces, qué debería hacer?

En Python 2: heredar siempre de objectexplícitamente . Obtenga las ventajas.

En Python 3: hereda de objectsi estás escribiendo código que intenta ser independiente de Python, es decir, debe funcionar tanto en Python 2 como en Python 3. De lo contrario, no lo hagas, realmente no hay diferencia ya que Python lo inserta por ti. entre bastidores.

Pitón 3

  • class MyClass(object):= Clase de nuevo estilo
  • class MyClass:= Clase de nuevo estilo (hereda implícitamente de object)

Pitón 2

  • class MyClass(object):= Clase de nuevo estilo
  • class MyClass:= CLASE AL ANTIGUO ESTILO

Explicación :

Al definir clases base en Python 3.x, puede eliminarlas objectde la definición. Sin embargo, esto puede abrir la puerta a un problema muy 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 sobre 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 sintaxis de las clases de estilo antiguo en Python 2.x es la misma que la sintaxis alternativa para las clases de estilo nuevo en Python 3.x. Python 2.x todavía se usa ampliamente (p. ej., GAE, Web2Py), y cualquier código (o codificador) que, sin saberlo, introduzca definiciones de clases de estilo 3.x en código 2.x terminará con algunos objetos base seriamente obsoletos. Y como las clases al viejo estilo no están en el radar de nadie, es probable que no sepan qué les pasó.

Así que explíquelo detalladamente y ahorre las lágrimas a algún desarrollador 2.x.

Yarin avatar Feb 25 '2012 21:02 Yarin

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

Los objetos de nuevo estilo 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()y @propertydescriptores. Consulte este artículo para obtener una buena descripción de qué es una nueva clase de estilo.

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

Jerub avatar Oct 25 '2010 14:10 Jerub