Bien que la raison soit principalement historique, il y a certaines particularités dans Python len
qui 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.index
et dict.append
, tandis que d'autres sont implémentées en tant que méthodes appelables et magiques, par exemple str
et iter
et reversed
. Les deux groupes diffèrent suffisamment pour que l'approche différente soit justifiée:
- Ils sont communs.
str
, int
et 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,
iter
peut 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 for
boucle. 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 -
repr
agissent comme str
si. 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.a
et getattr
partagent 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, len
ne 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, len
vous pouvez rompre bool(x)
avec une len
mé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 len
c'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.