web-dev-qa-db-fra.com

La classe Python hérite de l'objet

Existe-t-il une raison pour qu'une déclaration de classe hérite de object?

Je viens de trouver un code qui fait cela et je ne peux pas trouver une bonne raison pour cela.

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

Existe-t-il une raison pour qu'une déclaration de classe hérite de object?

Dans Python 3, mis à part la compatibilité entre Python 2 et 3, sans raison . Dans Python 2, , plusieurs raisons .


Histoire Python 2.x:

Dans Python 2.x (à partir de 2.2), deux styles de classes dépendent de la présence ou non de object en tant que classe de base:

  1. style "classique" classes: elles n'ont pas object comme classe de base:

    _>>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    _
  2. "nouveau" style classes: elles ont, directement ou indirectement (par exemple héritées d'un type intégré ), object en tant que classe de 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'>,)
    _

Sans aucun doute, lors de l'écriture d'une classe, vous voudrez toujours choisir des classes de nouveau style. Les avantages de le faire sont nombreux, pour en énumérer quelques-uns:

  • Support pour les descripteurs . Plus précisément, les constructions suivantes sont possibles avec des descripteurs:

    1. classmethod : Une méthode qui reçoit la classe sous forme d'argument implicite à la place de l'instance.
    2. staticmethod : Une méthode qui ne reçoit pas l'argument implicite self en tant que premier argument.
    3. propriétés avec property : Créer des fonctions pour gérer l'obtention, la définition et la suppression d'un attribut.
    4. __slots__ : Enregistre les consommations de mémoire d'une classe et accélère également l'accès aux attributs. Bien sûr, cela fait impose des limitations .
  • La méthode __new__ statique: vous permet de personnaliser le mode de création des nouvelles instances de classe.

  • ordre de résolution de méthode (MRO) : dans quel ordre les classes de base d'une classe seront recherchées lors de la tentative de résolution de la méthode à appeler.

  • Relatif à MRO, super appelle . Voir aussi, super() considéré comme super.

Si vous n'héritez pas de object, oubliez cela. Une description plus exhaustive des points précédents avec d'autres avantages des "nouvelles" classes de style peut être trouvée ici .

Un des inconvénients des classes de style nouveau est que la classe elle-même est plus exigeante en mémoire. Cependant, à moins de créer de nombreux objets de classe, je doute que ce soit un problème et que ce soit un naufrage négatif dans une mer de positifs.


Histoire Python 3.x:

Dans Python 3, les choses sont simplifiées. Seules les classes de style nouveau existent (appelées simplement classes). La seule différence en ajoutant object vous oblige donc à saisir 8 caractères supplémentaires. Cette:

_class ClassicSpam:
    pass
_

est complètement équivalent (à part leur nom :-) à ceci:

_class NewSpam(object):
     pass
_

et à ceci:

_class Spam():
    pass
_

Tous ont object dans leur ___bases___.

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

Alors, que devrais-tu faire?

Dans Python 2: toujours hériter de object explicitement . Obtenez les avantages.

Dans Python 3: héritez de object si vous écrivez du code qui essaie d'être Python agnostique, C’est-à-dire qu’il doit fonctionner à la fois dans Python 2 et dans Python 3. Sinon, cela ne fait vraiment aucune différence puisque Python l’insère pour vous derrière les scènes.

557

Python 3

  • class MyClass(object): = Classe de style nouveau
  • class MyClass: = Classe de style nouveau (hérite implicitement de object)

Python 2

  • class MyClass(object): = Classe de style nouveau
  • class MyClass: = CLASSE DE STYLE ANCIEN

Explication:

Lorsque vous définissez des classes de base dans Python 3.x, vous êtes autorisé à supprimer le object de la définition. Cependant, cela peut ouvrir la porte à un problème très difficile à suivre…

Python a introduit les classes de nouveau style dans Python 2.2, et les classes de style ancien sont maintenant très anciennes. La discussion sur les classes de style ancien est enterrée dans les documents 2.x , et inexistante dans les documents 3.x.

Le problème est que la syntaxe des classes de style ancien dans Python 2.x est identique à la syntaxe alternative des classes de style nouveau dans Python 3.x . Python 2.x est encore très largement utilisé (par exemple, GAE, Web2Py), et tout code (ou codeur) introduisant involontairement des définitions de classe de style 3.x dans du code 2.x se retrouvera avec objets de base sérieusement obsolètes. Et comme les classes à l’ancienne ne sont pas considérées par tous, ils ne sauront probablement pas ce qui les frappe.

Donc, épelez-le sur le long chemin et sauvez un développeur 2.x des larmes.

517
Yarin

Oui, c'est un objet 'nouveau style'. C'était une fonctionnalité introduite dans python2.2.

Les nouveaux objets de style ont un modèle différent de celui des objets classiques et certaines choses ne fonctionneront pas correctement avec les anciens objets de style, par exemple, super(), @property et des descripteurs. Voir cet article pour une bonne description de ce qu'est une nouvelle classe de style.

Lien SO pour une description des différences: Quelle est la différence entre l'ancien style et les nouvelles classes de style en Python?

397
Jerub

Histoire de Apprendre Python à la dure :

L'interprétation originale d'une classe par Python était cassée de nombreuses manières sérieuses. Au moment où cette faute a été reconnue, il était déjà trop tard et ils ont dû la supporter. Afin de résoudre le problème, ils avaient besoin d'un style "nouvelle classe" pour que les "anciennes classes" continuent de fonctionner, mais vous pouvez utiliser la nouvelle version plus correcte.

Ils ont décidé d'utiliser un "objet" Word, en minuscule, pour être la "classe" dont vous héritez pour en faire une classe. C'est déroutant, mais une classe hérite de la classe nommée "objet" pour en faire une classe mais ce n'est pas un objet mais une classe, mais n'oubliez pas d'hériter d'un objet.

Également, pour que vous sachiez quelle est la différence entre les classes de style nouveau et les classes de style ancien, c’est que les classes de style nouveau héritent toujours de la classe object ou d’une autre classe héritée de object:

class NewStyle(object):
    pass

Un autre exemple est:

class AnotherExampleOfNewStyle(NewStyle):
    pass

Alors qu'une classe de base à l'ancienne ressemble à ceci:

class OldStyle():
    pass

Et une classe enfant de style ancien ressemble à ceci:

class OldStyleSubclass(OldStyle):
    pass

Vous pouvez constater qu'une classe de base Old Style n'hérite d'aucune autre classe. Cependant, les classes Old Style peuvent bien entendu hériter les unes des autres. Hériter d'un objet garantit que certaines fonctionnalités sont disponibles dans chaque classe Python. De nouvelles classes de style ont été introduites dans Python 2.2

30
disp_name

Oui, c'est historique . Sans cela, il crée une classe de style ancien.

Si vous utilisez type() sur un objet de style ancien, vous obtenez simplement "instance". Sur un objet de style nouveau, vous obtenez sa classe.

28
knitti

La syntaxe de l'instruction de création de classe:

class <ClassName>(superclass):
    #code follows

En l'absence de toute autre super-classe dont vous souhaitez spécifiquement hériter, superclass doit toujours être object, qui est la racine de toutes les classes en Python.

object est techniquement la racine des classes "new-style" en Python. Mais les classes de nouveau style sont aussi bonnes que le seul style de classe.

Toutefois, si vous n'utilisez pas explicitement Word object lors de la création de classes, alors, comme d'autres l'ont mentionné, Python 3.x hérite implicitement de la superclasse object. Mais je suppose qu'explicite est toujours mieux qu'implicite (enfer)

référence

6
kmario23