875 votos

De estilo antiguo y el nuevo estilo de las clases en Python

¿Cuál es la diferencia entre estilo antiguo y el nuevo estilo de las clases en Python? ¿Hay siempre una razón para usar el viejo estilo de las clases en estos días?

498voto

Mark Cidade Puntos 53945

De http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes :

Hasta Python 2.1, de estilo antiguo, las clases eran el único sabor disponibles para el usuario. El concepto de (estilo antiguo) de la clase no está relacionado con el concepto de tipo: si x es una instancia de una clase de estilo, a continuación, x.__class__ designa la clase de x, pero type(x) siempre <type 'instance'>. Esto refleja el hecho de que todo el viejo estilo de los casos, independientemente de su clase, se llevan a cabo con un único tipo integrado, llamado instancia.

De nuevo estilo que se introdujeran las clases en Python 2.2 para unificar las clases y tipos. Un nuevo estilo de clase ni más ni menos que un tipo definido por el usuario. Si x es una instancia de una nueva clase de estilo, a continuación, type(x) es el mismo como x.__class__.

La principal motivación para la introducción de nuevos estilo de las clases es proporcionar un sistema unificado de modelo de objetos con un total meta-modelo. También cuenta con una serie de beneficios inmediatos, como la capacidad para crear subclases de la mayoría de los tipos integrados, o la introducción de "descriptores", que permiten calculada propiedades.

Por razones de compatibilidad, las clases aún de viejo estilo por defecto. Nuevo estilo de clases se crean mediante la especificación de un nuevo estilo de clase (ej. un tipo) como una clase padre, o el "tipo de nivel superior" objetos si no hay otro padre que se necesita. El comportamiento de las clases de estilo difiere del estilo antiguo de clases en una serie de detalles importantes, además de qué tipo de devoluciones. Algunos de estos cambios son fundamentales en el nuevo modelo de objetos, como la forma especial de los métodos se invocan. Otros son "parches" que no podría ser implementado antes por problemas de compatibilidad, como el método de la resolución de la orden en el caso de herencia múltiple.

Python 3 sólo tiene nuevo estilo de clases. No importa si usted subclase de object o no, las clases son de un estilo nuevo en Python 3. Sin embargo es recomendable que usted todavía subclase de object.

284voto

Mark Harrison Puntos 77152

Declaración-sabio:

Nuevo estilo de clases heredan de object, o de otro estilo nuevo de la clase.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

De estilo antiguo clases no.

class OldStyleClass():
    pass

202voto

Ciro Santilli Puntos 3341

Importante los comportamientos de los cambios entre el antiguo y el nuevo estilo de las clases:

  • super añadido
  • MRO cambiado (se explica abajo)
  • descriptores añadido
  • nuevo estilo los objetos de la clase no puede ser elevado a menos que se derivan de Exception (ejemplo a continuación)
  • __slots__ añadido

MRO cambiado

Fue mencionado en otras respuestas, pero aquí va un ejemplo concreto de la diferencia entre el clásico MRO y C3 MRO (utilizado en el nuevo estilo de las clases).

La pregunta es el orden en el que los atributos (que incluyen métodos y variables miembro) se buscan en la herencia múltiple.

Clásico clases de realizar una profundidad de buscar primero de izquierda a derecha. Parada en el primer partido. Ellos no tienen la __mro__ de atributo.

class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 0
assert C21().i == 2

try:
    C12.__mro__
except AttributeError:
    pass
else:
    assert False

Nuevo estilo de clases MRO es más complicado sintetizar en una sola de las frases en inglés. Esto se explica en detalle aquí. Una de sus propiedades es que una clase Base sólo es buscado por una vez todas sus clases Derivadas han sido. Ellos tienen la __mro__ atributo que muestra el orden de búsqueda.

class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 2
assert C21().i == 2

assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)

Nuevo estilo los objetos de la clase no puede ser elevado a menos que se derivan de Exception

Alrededor de Python 2.5 muchas clases podría ser elevado, alrededor de Python 2.6 esto fue eliminado. En Python 2.7.3:

# OK, old:
class Old: pass
try:
    raise Old()
except Old:
    pass
else:
    assert False

# TypeError, new not derived from `Exception`.
class New(object): pass
try:
    raise New()
except TypeError:
    pass
else:
    assert False

# OK, derived from `Exception`.
class New(Exception): pass
try:
    raise New()
except New:
    pass
else:
    assert False

# `'str'` is a new style object:
try:
    raise 'str'
except TypeError:
    pass
else:
    assert False

35voto

xioxox Puntos 667

De estilo antiguo, las clases son todavía un poco más rápido para el atributo de búsqueda. Esto generalmente no es importante, pero puede ser útil en el desempeño sensible Python 2.x código:

En [3]: clase a:
 ...: def __init__(self):
 ...: self.a = 'hola'
 ...: 

En [4]: clase B(objeto):
 ...: def __init__(self):
 ...: self.a = 'hola'
 ...: 

En [6]: aobj = Un(a)
En [7]: bobj = B()

En [8]: %timeit aobj.a
10000000 de bucles, la mejor de las 3: 78.7 ns por bucle

En [10]: %timeit bobj.a
10000000 de bucles, la mejor de las 3: 86.9 ns por bucle

30voto

Xiao Hanyu Puntos 131

Guido ha escrito la Historia de La Nueva-las Clases de Estilo, realmente un muy buen artículo acerca de un estilo nuevo y el viejo estilo de la clase en Python.

Python 3 tiene solamente un estilo nuevo de la clase, incluso si usted escribe un 'estilo antiguo', implícitamente se derivan de object.

Nuevo estilo en clases avanzadas características de las que carecen en el viejo estilo de las clases, tales como super y el nuevo C3 mro, algo mágico y métodos, etc.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X