1085 votes

Style ancien et nouveau style de classes en Python

Quelle est la différence entre le style ancien et nouveau style de classes en Python? Est-il toujours une raison d'utiliser de vieux-classes de style de ces jours?

605voto

Mark Cidade Points 53945

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

Jusqu'à Python 2.1, de style ancien classes ont été le seul de la saveur à la disposition de l'utilisateur. Le concept de (vieux style) de classe n'est pas liée à la notion de type: si x est une instance d'une classe de style, alors x.__class__ désigne la classe d' x, mais type(x) toujours <type 'instance'>. Cela reflète le fait que tous les anciens de style instances, indépendamment de leur classe, sont mis en œuvre avec un seul type, appelé instance.

Nouveau style de classes ont été introduites en Python 2.2 pour unifier les classes et les types. Un nouveau style de classe ni plus ni moins que d'un type défini par l'utilisateur. Si x est une instance de la classe de style, alors type(x) est le même que x.__class__.

La principale motivation pour l'introduction de la nouvelle-classes de style est de fournir un objet unifié modèle avec un méta-modèle. Il a également un certain nombre d'avantages immédiats, comme la capacité de la sous-classe la plupart des types intégrés, ou l'introduction de "descripteurs", qui permettent aux propriétés calculées.

Pour des raisons de compatibilité, les classes sont toujours ancien de style par défaut. Nouveau style de classes sont créées en spécifiant un autre nouveau type de classe (c'est à dire un type) comme une classe parent, ou le "haut-niveau" type d'objet si aucun autre parent est nécessaire. Le comportement de la nouvelle-classes de style diffère de celui de l'ancien-classes de style dans un certain nombre de détails importants, en plus de ce type de déclarations. Certains de ces changements sont fondamentaux pour le nouveau modèle objet, comme le fait de spécial méthodes sont invoquées. D'autres sont des "corrections" qui n'a pas pu être mis en œuvre avant pour les problèmes de compatibilité, comme la méthode de résolution de l'ordre dans le cas de l'héritage multiple.

Python 3 a seulement la nouvelle-classes de style. Peu importe si vous sous-classe d' object ou pas, les classes sont nouveau style en Python 3. Il est cependant recommandé que vous avez encore sous-classe d' object.

329voto

Mark Harrison Points 77152

Déclaration:

Nouveau style de classes héritent de l'objet, ou à partir d'un autre style nouveau de la classe.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

De style ancien classes ne pas.

class OldStyleClass():
    pass

239voto

Ciro Santilli Points 3341

D'importants changements de comportements entre les anciens et les nouvelles classes de style:

  • super ajouté
  • MRO changé (expliqué ci-dessous)
  • descripteurs ajouté
  • nouveau style des objets de la classe ne peut être levé que si dérivée de l' Exception (exemple ci-dessous)
  • __slots__ ajouté

MRO changé

Il a été mentionné dans d'autres réponses, mais voilà un exemple concret de la différence entre le classique MRO et C3 MRO (utilisé dans les nouvelles classes de style).

La question est à l'ordre dans lequel les attributs (qui comprennent les méthodes et les variables membres) sont recherchés dans l'héritage multiple.

Classique des classes de faire un parcours en profondeur d'abord de recherche de gauche à droite. Arrêt sur le premier match. Ils n'ont pas l' __mro__ d'attribut.

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

New-classes de style MRO est plus compliqué de synthétiser en une seule phrase anglaise. Il est expliqué en détail ici. L'une de ses propriétés, c'est qu'une classe de Base est uniquement cherché pour une fois que l'ensemble de ses classes Dérivées ont été. Ils ont l' __mro__ attribut qui indique l'ordre de recherche.

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)

Nouveau style des objets de la classe ne peut être levé que si dérivée de l' Exception

Autour de Python 2.5 le nombre de classes qui peuvent être posées, autour de Python 2.6 cela a été supprimé. Sur 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

41voto

xioxox Points 667

De style ancien, les classes sont toujours légèrement plus rapide pour l'attribut de recherche. Ce n'est généralement pas important, mais peut être utile dans la performance sensible Python 2.x code:

Dans [3]: classe A:
 ...: def __init__(self):
 ...: auto.a = 'bonjour'
 ...: 

Dans [4]: classe B(objet):
 ...: def __init__(self):
 ...: auto.a = 'bonjour'
 ...: 

Dans [6]: aobj = A()
Dans [7]: bobj = B()

Dans [8]: %timeit aobj.un
10000000 boucles, best of 3: 78.7 ns par boucle

Dans [10]: %timeit bobj.un
10000000 boucles, best of 3: 86.9 ns par boucle

38voto

Xiao Hanyu Points 131

Guido a écrit l'Histoire à L'Intérieur sur la Nouvelle-Classes de Style, un très bon article sur le style nouveau et vieux style de classe en Python.

Python 3 n'a qu'un style nouveau de la classe, même si vous écrivez un "vieux de la classe de style", il est implicitement dérivée d' object.

Nouveau style de classes ont certaines fonctionnalités avancées manque dans le vieux-classes de style, tels que l' super et la nouvelle C3 mro, magique méthodes, etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X