103 votes

Pourquoi python utilise-t-il des "méthodes magiques"?

J'ai été jouer avec un Python récemment, et une chose que je trouve un peu bizarre est l'utilisation extensive de la " magie des méthodes, par exemple pour faire sa longueur d'un objet implémente une méthode def __len__(self) et puis il est appelé lorsque vous écrivez len(obj).

Je me demandais juste pourquoi les objets ne sont pas simplement définir une len(self) méthode et l'ont appelé directement en tant que membre de l'objet, par exemple, obj.len()? Je suis sûr qu'il y a de bonnes raisons pour Python le faire de la même manière qu'il le fait, mais en tant que novice, je n'ai pas travaillé sur ce qu'ils sont encore.

65voto

Eli Bendersky Points 82298

Autant que je sache, len est spécial à cet égard et a de profondes racines historiques.

Voici une citation de la FAQ:

Pourquoi Python utiliser des méthodes pour certains fonctionnalité (par exemple, liste.index ()), mais fonctions pour d'autres (par exemple, len(liste))?

La raison majeure est de l'histoire. Fonctions ont été utilisés pour ces opérations, qui ont été générique pour un groupe de types et de qui étaient destinés à travailler, même pour les objets qui n'ont pas les méthodes à (par exemple des n-uplets). Il est également pratique d'avoir une fonction qui peut être facilement appliqué à un amorphe collection d'objets lorsque vous utilisez le caractéristiques fonctionnelles de Python (map(), appliquer() et al).

En fait, la mise en œuvre de len(), max(), min() comme une fonction intégrée est en fait moins de code que la mise en œuvre de comme des méthodes pour chaque type. On peut ergoter sur des cas individuels, mais c'est une partie de Python, et c'est trop tard pour apporter des changements fondamentaux tels maintenant. Les fonctions doivent rester à éviter massive du code de la rupture.

L'autre "magique méthodes" (en fait appelée méthode spéciale dans le Python folklore) faire beaucoup de sens, et une fonctionnalité similaire existe dans d'autres langues. Ils sont principalement utilisés pour le code qui est appelé implicitement lors de la syntaxe spéciale.

Par exemple:

  • surcharge des opérateurs (existent en C++ et autres)
  • constructeur/destructeur
  • crochets pour accéder aux attributs
  • outils pour la métaprogrammation

et ainsi de suite...

22voto

AndiDog Points 28417

À partir du Zen de Python:

Dans le visage de l'ambiguïté, de refuser la tentation de le deviner.
Il devrait y avoir un, et de préférence seulement une façon évidente de le faire.

C'est l'une des raisons - avec des méthodes personnalisées, les développeurs seraient libres de choisir un autre nom de la méthode, comme getLength(), length(), getlength() ou que ce soit. Python applique une stricte de nommage, de sorte que la fonction courante, len() peut être utilisé.

Toutes les opérations qui sont communs à de nombreux types d'objets sont mis dans les méthodes magiques, comme __nonzero__, __len__ ou __repr__. Ils sont pour la plupart en option, cependant.

La surcharge d'opérateur est également fait avec les méthodes magiques (par exemple, __le__), il est donc logique de les utiliser pour d'autres opérations courantes, de trop.

9voto

Ian Bicking Points 4571

Certaines de ces fonctions à faire plus qu'une seule méthode de mesure à mettre en œuvre (sans méthodes abstraites sur une super-classe). Par exemple, bool() des actes un peu comme ceci:

def bool(obj):
    if hasattr(obj, '__bool__'):
        return bool(obj.__nonzero__())
    elif hasattr(obj, '__len__'):
        if obj.__len__():
            return True
        else:
            return False
    return True

Vous pouvez également être sûr à 100% que bool() retourne toujours True ou False; si vous avez une méthode, vous ne pouviez pas être entièrement sûr de ce que vous obtiendrez en retour.

Quelques autres fonctions qui ont relativement compliqué implémentations (plus compliqué que le sous-jacent de la magie méthodes sont susceptibles de l'être) sont iter() et cmp(), et tous les attribut méthodes (getattr, setattr et delattr). Des choses comme int également accéder à des méthodes magiques quand on fait de la contrainte (vous pouvez implémenter __int__), mais ne double devoir en tant que types. len(obj) est en fait le seul cas où je ne crois pas que c'est toujours différent de obj.__len__().

4voto

Stefano Borini Points 36904

Ce ne sont pas vraiment des "noms magiques". C'est simplement l'interface qu'un objet doit implémenter pour fournir un service donné. En ce sens, elles ne sont pas plus magiques que n'importe quelle définition d'interface prédéfinie que vous devez réimplémenter.

0voto

user318904 Points 1335

Il n'y a pas beaucoup de choses à ajouter à ces deux postes, mais toute la "magie" des fonctions ne sont pas vraiment de la magie. Ils font partie de l' __ les builtins__ module qui est implicitement/importés automatiquement lorsque l'interprète commence. C'est à dire:

from __builtins__ import *

arrive à chaque fois avant le début de votre programme.

J'ai toujours pensé qu'il serait plus correct si python seulement fait pour le shell interactif, et des scripts requis pour importer les diverses parties d'objets internes dont ils ont besoin. Probablement aussi différents __ principaux__ la manipulation serait bien en coquilles vs interactive. De toute façon, découvrez toutes les fonctions, et de voir ce que c'est que sans eux:

dir (__builtins__)
...
del __builtins__

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