Si bien la razón es principalmente histórica, existen algunas peculiaridades en la len
que hacen que el uso de una función en lugar de un método sea apropiado.
Algunas operaciones en Python se implementan como métodos, por ejemplo list.index
y dict.append
, mientras que otras se implementan como métodos invocables y mágicos, por ejemplo str
y iter
y reversed
. Los dos grupos difieren lo suficiente como para justificar el enfoque diferente:
- Son comunes.
str
, int
Y los amigos son tipos. Tiene más sentido llamar al constructor.
- La implementación difiere de la llamada a la función. Por ejemplo,
iter
podría llamar __getitem__
si __iter__
no está disponible y admite argumentos adicionales que no encajan en una llamada de método. Por la misma razón it.next()
se ha cambiado anext(it)
en versiones recientes de Python: tiene más sentido.
- Algunos de ellos son parientes cercanos de los operadores. Hay sintaxis para llamar
__iter__
y __next__
se llama for
bucle. Por coherencia, una función es mejor. Y lo hace mejor para ciertas optimizaciones.
- Algunas de las funciones son simplemente demasiado similares al resto de alguna manera:
repr
actúa como lo str
hace. Tener str(x)
versusx.repr()
sería confuso.
- Algunos de ellos rara vez utilizan el método de implementación real, por ejemplo
isinstance
.
- Algunos de ellos son operadores reales,
getattr(x, 'a')
es otra forma de hacer x.a
y getattr
comparte muchas de las cualidades antes mencionadas.
Yo personalmente llamo al primer grupo como método y al segundo grupo como operador. No es una distinción muy buena, pero espero que ayude de alguna manera.
Dicho esto, len
no encaja exactamente en el segundo grupo. Está más cerca de las operaciones en la primera, con la única diferencia de que es mucho más común que casi todas. Pero lo único que hace es llamar __len__
, y está muy cerca L.index
. Sin embargo, hay algunas diferencias. Por ejemplo, __len__
podría ser llamado para la implementación de otras características, como por ejemplo bool
, si se llamó al método len
, podría romper bool(x)
con un len
método personalizado que hace algo completamente diferente.
En resumen, tiene un conjunto de características muy comunes que las clases pueden implementar a las que se puede acceder a través de un operador, a través de una función especial (que generalmente hace más que la implementación, como lo haría un operador), durante la construcción del objeto, y todas ellas. comparten algunos rasgos comunes. Todo lo demás es un método. Y len
es una excepción a esa regla.
len()
o sereversed()
aplica a muchos tipos de objetos, pero un método comoappend()
solo se aplica a secuencias, etc.