Pregunta La clase Python hereda el objeto


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

Acabo de encontrar un código que hace esto y no puedo encontrar un buen motivo.

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

752
2017-10-25 14:15


origen


Respuestas:


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

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


Historia de Python 2.x:

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

  1. "estilo clásico clases: no tienen object como una clase base:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. "nuevo estilo clases: tienen, directamente o indirectamente (por ejemplo, heredar de un tipo incorporado), object como una 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 lugar a dudas, al escribir una clase, siempre quiero ir a clases de nuevo estilo Las ventajas de hacerlo son numerosas, para enumerar algunas de ellas:

  • Soporte para descriptores. Específicamente, los siguientes constructos son posibles con descriptores:

    1. classmethod: Un método que recibe la clase como un argumento implícito en lugar de la instancia.
    2. staticmethod: Un método que no recibe el argumento implícito self como primer argumento
    3. propiedades con property: Crear 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 da como resultado un acceso más rápido a los atributos. Claro que lo hace imponer limitaciones.
  • los __new__ método estático: le permite personalizar cómo se crean las nuevas instancias de clase.

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

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

Si no heredas de objectolvida estos. Se 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 estilo nuevo es que la clase en sí es más exigente con la memoria. Sin embargo, a menos que estés creando muchos objetos de clase, dudo que esto sea un problema y es un hundimiento negativo en un mar de aspectos positivos.


Historia de Python 3.x:

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

class ClassicSpam:
    pass

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

class NewSpam(object):
     pass

y a esto:

class Spam():
    pass

todos tienen object en su __bases__.

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

¿Entonces, qué debería hacer?

En Python 2:  siempre heredar de object explícitamente. Obtenga los beneficios.

En Python 3: heredar de object si está escribiendo código que intenta ser independiente de Python, es decir, necesita funcionar tanto en Python 2 como en Python 3. De lo contrario, no importa, ya que Python lo inserta detrás de escena.


243
2017-07-12 15:34



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

Python 2.x:
class MyClass(object): = clase de nuevo estilo
class MyClass: = CLASE DE ANTIGUO ESTILO

Explicación:

Al definir las clases base en Python 3.x, puede eliminar el objeto de la definición. Sin embargo, esto puede abrir la puerta a un problema seriamente difícil de rastrear ...

Python introdujo las clases de nuevo estilo en Python 2.2, y ahora las clases antiguas son bastante antiguas. La discusión de las clases de estilo antiguo es enterrado en los documentos 2.x.e inexistente en los documentos 3.x.

El problema es, la sintaxis para 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 sigue siendo muy utilizado (por ejemplo, GAE, Web2Py), y cualquier código (o codificador) que involuntariamente traiga definiciones de clases de estilo 3.x al código 2.x terminará con algunos objetos base seriamente desactualizados. Y como las clases de estilo antiguo no están en el radar de nadie, es probable que no sepan qué las golpeó.

Así que solo deletérelo por el camino largo y ahorre un poco de lágrimas al desarrollador 2.x.


494
2018-02-25 21:15



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

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

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


388
2017-10-25 14:20



Historia de Aprende Python de la manera difícil:

La versión original de Python de una clase se rompió en muchos casos serios   formas. Para cuando se reconoció esta falla, ya era demasiado tarde,   y tuvieron que apoyarlo. Para solucionar el problema, necesitaban   un estilo de "nueva clase" para que las "viejas clases" siguieran funcionando   pero puedes usar la nueva versión más correcta.

Decidieron que usarían una palabra "objeto", en minúscula, para ser   la "clase" de la que heredas para formar una clase. Es confuso,   pero una clase hereda de la clase llamada "objeto" para hacer una clase pero   no es un objeto realmente es una clase, pero no te olvides de heredar   del objeto.

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

class NewStyle(object):
    pass

Otro ejemplo es:

class AnotherExampleOfNewStyle(NewStyle):
    pass

Mientras que una clase base antigua se ve así:

class OldStyle():
    pass

Y una clase infantil de estilo antiguo se ve así:

class OldStyleSubclass(OldStyle):
    pass

Puede ver que una clase base de estilo antiguo no hereda de ninguna otra clase, sin embargo, las clases de estilo antiguo pueden, por supuesto, heredarse entre sí. Heredar de un objeto garantiza que cierta funcionalidad esté disponible en cada clase de Python. Se introdujeron nuevas clases de estilo en Python 2.2


29
2017-11-04 10:54



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

Si utiliza type() en un objeto antiguo, simplemente obtienes "instancia". En un objeto de estilo nuevo, obtienes su clase.


23
2017-10-25 14:20



La sintaxis de la declaración de creación de clases:

class <ClassName>(superclass):
    #code follows

En ausencia de otras superclases de las que específicamente desee heredar, superclass siempre debe ser 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 hoy en día son tan buenas como ser el único estilo de clases.

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

Referencia


6
2017-10-20 05:37



Esto crea un clase de nuevo estilo.


1
2017-10-25 14:20