Bien que la raison soit principalement historique, il y a certaines particularités dans Python lenqui rendent l'utilisation d'une fonction au lieu d'une méthode appropriée.
Certaines opérations en Python sont implémentées en tant que méthodes, par exemple list.indexet dict.append, tandis que d'autres sont implémentées en tant que méthodes appelables et magiques, par exemple stret iteret reversed. Les deux groupes diffèrent suffisamment pour que l'approche différente soit justifiée:
- Ils sont communs.
str, intet les amis sont des types. Il est plus logique d'appeler le constructeur.
- L'implémentation diffère de l'appel de fonction. Par exemple,
iterpeut appeler __getitem__si __iter__n'est pas disponible et prend en charge des arguments supplémentaires qui ne rentrent pas dans un appel de méthode. Pour la même raison, it.next()a été changé ennext(it) les versions récentes de Python - cela a plus de sens.
- Certains d'entre eux sont des parents proches des exploitants. Il y a une syntaxe pour appeler
__iter__et __next__- ça s'appelle la forboucle. Par souci de cohérence, une fonction est meilleure. Et cela le rend meilleur pour certaines optimisations.
- Certaines fonctions sont tout simplement trop similaires aux autres d'une certaine manière -
repragissent comme strsi. Avoir str(x)contre x.repr()serait déroutant.
- Certains d'entre eux utilisent rarement la méthode de mise en œuvre réelle, par exemple
isinstance.
- Certains d'entre eux sont de véritables opérateurs,
getattr(x, 'a')c'est une autre façon de faire x.aet getattrpartagent plusieurs des qualités susmentionnées.
J'appelle personnellement le premier groupe de type méthode et le second groupe de type opérateur. Ce n'est pas une très bonne distinction, mais j'espère que cela aide d'une manière ou d'une autre.
Cela dit, lenne rentre pas exactement dans le deuxième groupe. C'est plus proche des opérations du premier, à la seule différence que c'est beaucoup plus courant que presque n'importe lequel d'entre eux. Mais la seule chose qu'il fait, c'est d'appeler __len__, et c'est très proche L.index. Cependant, il existe quelques différences. Par exemple, __len__peut être appelé pour l'implémentation d'autres fonctionnalités, par exemple bool, si la méthode a été appelée, lenvous pouvez rompre bool(x)avec une lenméthode personnalisée qui fait des choses complètement différentes.
En bref, vous avez un ensemble de fonctionnalités très courantes que les classes pourraient implémenter et qui pourraient être accessibles via un opérateur, via une fonction spéciale (qui fait généralement plus que l'implémentation, comme le ferait un opérateur), lors de la construction d'objet, et toutes partagent certains traits communs. Tout le reste est une méthode. Et lenc'est en quelque sorte une exception à cette règle.
len()oureversed()s'applique à de nombreux types d'objets, mais une méthode telle queappend()ne s'applique qu'aux séquences, etc.